@amityco/ts-sdk-react-native 7.13.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.
- package/dist/@types/domains/client.d.ts +10 -1
- package/dist/@types/domains/client.d.ts.map +1 -1
- package/dist/@types/domains/feed.d.ts +17 -1
- package/dist/@types/domains/feed.d.ts.map +1 -1
- package/dist/@types/domains/message.d.ts +1 -1
- package/dist/@types/domains/message.d.ts.map +1 -1
- package/dist/@types/domains/post.d.ts +5 -0
- package/dist/@types/domains/post.d.ts.map +1 -1
- package/dist/client/api/accessTokenExpiryWatcher.d.ts +1 -1
- package/dist/client/api/accessTokenExpiryWatcher.d.ts.map +1 -1
- package/dist/client/api/index.d.ts +2 -0
- package/dist/client/api/index.d.ts.map +1 -1
- package/dist/client/api/isSameUserId.d.ts +2 -0
- package/dist/client/api/isSameUserId.d.ts.map +1 -0
- package/dist/client/api/login.d.ts.map +1 -1
- package/dist/client/api/loginAsBot.d.ts.map +1 -1
- package/dist/client/api/loginAsVisitor.d.ts.map +1 -1
- package/dist/client/api/loginWithAccessToken.d.ts +28 -0
- package/dist/client/api/loginWithAccessToken.d.ts.map +1 -0
- package/dist/client/api/logout.d.ts.map +1 -1
- package/dist/client/api/renewTokenWithHandler.d.ts +11 -0
- package/dist/client/api/renewTokenWithHandler.d.ts.map +1 -0
- package/dist/client/api/renewWithAccessToken.d.ts +2 -0
- package/dist/client/api/renewWithAccessToken.d.ts.map +1 -0
- package/dist/client/api/resumeSession.d.ts.map +1 -1
- package/dist/client/api/setAccessTokenHandler.d.ts +31 -0
- package/dist/client/api/setAccessTokenHandler.d.ts.map +1 -0
- package/dist/client/api/setupLoginSubscriptions.d.ts +11 -0
- package/dist/client/api/setupLoginSubscriptions.d.ts.map +1 -0
- package/dist/client/api/tests/loginWithAccessToken.test.d.ts +2 -0
- package/dist/client/api/tests/loginWithAccessToken.test.d.ts.map +1 -0
- package/dist/client/api/validateAccessToken.d.ts +11 -0
- package/dist/client/api/validateAccessToken.d.ts.map +1 -0
- package/dist/commentRepository/api/createComment.d.ts.map +1 -1
- package/dist/commentRepository/api/deleteComment.d.ts.map +1 -1
- package/dist/commentRepository/events/utils.d.ts.map +1 -1
- package/dist/core/subscription.d.ts +2 -2
- package/dist/core/subscription.d.ts.map +1 -1
- package/dist/feedRepository/index.d.ts +1 -1
- package/dist/feedRepository/index.d.ts.map +1 -1
- package/dist/feedRepository/observers/getCommunityFeed/LiveCollectionController.d.ts +13 -0
- package/dist/feedRepository/observers/getCommunityFeed/LiveCollectionController.d.ts.map +1 -0
- package/dist/feedRepository/observers/getCommunityFeed/PaginationController.d.ts +5 -0
- package/dist/feedRepository/observers/getCommunityFeed/PaginationController.d.ts.map +1 -0
- package/dist/feedRepository/observers/getCommunityFeed/QueryStreamController.d.ts +15 -0
- package/dist/feedRepository/observers/getCommunityFeed/QueryStreamController.d.ts.map +1 -0
- package/dist/feedRepository/observers/getCommunityFeed.d.ts +34 -0
- package/dist/feedRepository/observers/getCommunityFeed.d.ts.map +1 -0
- package/dist/feedRepository/observers/index.d.ts +1 -0
- package/dist/feedRepository/observers/index.d.ts.map +1 -1
- package/dist/feedRepository/observers/utils.d.ts.map +1 -1
- package/dist/index.cjs.js +995 -385
- package/dist/index.esm.js +979 -369
- package/dist/index.umd.js +3 -3
- package/dist/postRepository/events/utils.d.ts.map +1 -1
- package/dist/postRepository/observers/utils.d.ts.map +1 -1
- package/dist/postRepository/utils/PostCommentCountEngine/CommentChange.d.ts +11 -0
- package/dist/postRepository/utils/PostCommentCountEngine/CommentChange.d.ts.map +1 -0
- package/dist/postRepository/utils/PostCommentCountEngine/CreateTask.d.ts +8 -0
- package/dist/postRepository/utils/PostCommentCountEngine/CreateTask.d.ts.map +1 -0
- package/dist/postRepository/utils/PostCommentCountEngine/DeleteTask.d.ts +7 -0
- package/dist/postRepository/utils/PostCommentCountEngine/DeleteTask.d.ts.map +1 -0
- package/dist/postRepository/utils/PostCommentCountEngine/PostCommentCountEngine.d.ts +19 -0
- package/dist/postRepository/utils/PostCommentCountEngine/PostCommentCountEngine.d.ts.map +1 -0
- package/dist/postRepository/utils/PostCommentCountEngine/ResetTask.d.ts +8 -0
- package/dist/postRepository/utils/PostCommentCountEngine/ResetTask.d.ts.map +1 -0
- package/dist/postRepository/utils/payload.d.ts.map +1 -1
- package/package.json +3 -1
- package/dist/commentRepository/internalApi/createComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/createComment.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/deleteComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/deleteComment.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/flagComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/flagComment.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/hardDeleteComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/hardDeleteComment.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/isCommentFlaggedByMe.d.ts +0 -2
- package/dist/commentRepository/internalApi/isCommentFlaggedByMe.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/queryComments.d.ts +0 -2
- package/dist/commentRepository/internalApi/queryComments.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/softDeleteComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/softDeleteComment.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/createComment.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/createComment.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/deleteComment.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/deleteComment.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/getCommentByIds.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/getCommentByIds.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/getComments.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/getComments.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/hardDeleteComment.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/hardDeleteComment.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/queryComments.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/queryComments.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/softDeleteComment.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/softDeleteComment.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/updateComment.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/updateComment.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/unflagComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/unflagComment.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/updateComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/updateComment.d.ts.map +0 -1
package/dist/index.esm.js
CHANGED
|
@@ -190,6 +190,12 @@ var FeedSourceEnum;
|
|
|
190
190
|
FeedSourceEnum["Community"] = "community";
|
|
191
191
|
FeedSourceEnum["User"] = "user";
|
|
192
192
|
})(FeedSourceEnum || (FeedSourceEnum = {}));
|
|
193
|
+
var FeedTypeEnum;
|
|
194
|
+
(function (FeedTypeEnum) {
|
|
195
|
+
FeedTypeEnum["Reviewing"] = "reviewing";
|
|
196
|
+
FeedTypeEnum["Published"] = "published";
|
|
197
|
+
FeedTypeEnum["Declined"] = "declined";
|
|
198
|
+
})(FeedTypeEnum || (FeedTypeEnum = {}));
|
|
193
199
|
|
|
194
200
|
var AmityEventType;
|
|
195
201
|
(function (AmityEventType) {
|
|
@@ -226,8 +232,8 @@ var AmityEventOrderOption;
|
|
|
226
232
|
|
|
227
233
|
function getVersion() {
|
|
228
234
|
try {
|
|
229
|
-
// the string ''v7.
|
|
230
|
-
return 'v7.
|
|
235
|
+
// the string ''v7.14.0-esm'' should be replaced by actual value by @rollup/plugin-replace
|
|
236
|
+
return 'v7.14.0-esm';
|
|
231
237
|
}
|
|
232
238
|
catch (error) {
|
|
233
239
|
return '__dev__';
|
|
@@ -1681,10 +1687,14 @@ const getLiveReactionTopic = (post) => {
|
|
|
1681
1687
|
};
|
|
1682
1688
|
const getRoomWatcherTopic = (room) => {
|
|
1683
1689
|
const user = getCurrentUser();
|
|
1690
|
+
if (!user)
|
|
1691
|
+
return;
|
|
1684
1692
|
return `${getNetworkId(user)}/room/${room._id}`;
|
|
1685
1693
|
};
|
|
1686
1694
|
const getRoomStreamerTopic = (room) => {
|
|
1687
1695
|
const user = getCurrentUser();
|
|
1696
|
+
if (!user)
|
|
1697
|
+
return;
|
|
1688
1698
|
return `${getNetworkId(user)}/room/${room.roomId}/streamer`;
|
|
1689
1699
|
};
|
|
1690
1700
|
function subscribeTopic(topic, callback) {
|
|
@@ -1779,13 +1789,13 @@ class NetworkActivitiesWatcher {
|
|
|
1779
1789
|
this._listener.clear();
|
|
1780
1790
|
}
|
|
1781
1791
|
}
|
|
1782
|
-
let instance$
|
|
1792
|
+
let instance$8;
|
|
1783
1793
|
var NetworkActivitiesWatcher$1 = {
|
|
1784
1794
|
getInstance: () => {
|
|
1785
|
-
if (!instance$
|
|
1786
|
-
instance$
|
|
1795
|
+
if (!instance$8) {
|
|
1796
|
+
instance$8 = new NetworkActivitiesWatcher();
|
|
1787
1797
|
}
|
|
1788
|
-
return instance$
|
|
1798
|
+
return instance$8;
|
|
1789
1799
|
},
|
|
1790
1800
|
};
|
|
1791
1801
|
|
|
@@ -22987,13 +22997,13 @@ class SessionWatcher {
|
|
|
22987
22997
|
this._listener.clear();
|
|
22988
22998
|
}
|
|
22989
22999
|
}
|
|
22990
|
-
let instance$
|
|
23000
|
+
let instance$7;
|
|
22991
23001
|
var SessionWatcher$1 = {
|
|
22992
23002
|
getInstance: () => {
|
|
22993
|
-
if (!instance$
|
|
22994
|
-
instance$
|
|
23003
|
+
if (!instance$7) {
|
|
23004
|
+
instance$7 = new SessionWatcher();
|
|
22995
23005
|
}
|
|
22996
|
-
return instance$
|
|
23006
|
+
return instance$7;
|
|
22997
23007
|
},
|
|
22998
23008
|
};
|
|
22999
23009
|
|
|
@@ -23570,6 +23580,108 @@ const setVisitorClientToken = async (params) => {
|
|
|
23570
23580
|
return { accessToken, users, userType };
|
|
23571
23581
|
};
|
|
23572
23582
|
|
|
23583
|
+
/* begin_public_function
|
|
23584
|
+
id: client.logout
|
|
23585
|
+
*/
|
|
23586
|
+
/**
|
|
23587
|
+
* ```js
|
|
23588
|
+
* import { Client } from '@amityco/ts-sdk-react-native';
|
|
23589
|
+
* const success = await Client.logout()
|
|
23590
|
+
* ```
|
|
23591
|
+
*
|
|
23592
|
+
* Disconnects an {@link Amity.Client} instance from ASC servers
|
|
23593
|
+
*
|
|
23594
|
+
* @returns a success boolean if disconnected
|
|
23595
|
+
*
|
|
23596
|
+
* @category Client API
|
|
23597
|
+
* @async
|
|
23598
|
+
*/
|
|
23599
|
+
const logout = async () => {
|
|
23600
|
+
var _a;
|
|
23601
|
+
const client = getActiveClient();
|
|
23602
|
+
client.log('client/api/disconnectClient');
|
|
23603
|
+
if (client.mqtt && client.mqtt.connected) {
|
|
23604
|
+
client.mqtt.disconnect();
|
|
23605
|
+
}
|
|
23606
|
+
/*
|
|
23607
|
+
* for cases when session state is terminated (example on ban) or token expired,
|
|
23608
|
+
* the terminating block will set session state to terminated or for the or
|
|
23609
|
+
* in the case of expired token the same happens
|
|
23610
|
+
*
|
|
23611
|
+
* establishing state also ignored in cases where accessTokenExpiryWatcher
|
|
23612
|
+
* calls renewal. There is a possibility that renewal will be called before
|
|
23613
|
+
* disconnectClient finishes execution
|
|
23614
|
+
*
|
|
23615
|
+
* IMPORTANT: call this before `emitter.all.clear()`, otherwise the session
|
|
23616
|
+
* event will never be triggered
|
|
23617
|
+
*/
|
|
23618
|
+
if (client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */)
|
|
23619
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
23620
|
+
client.emitter.all.clear();
|
|
23621
|
+
(_a = client.mqtt) === null || _a === void 0 ? void 0 : _a.removeAllListeners();
|
|
23622
|
+
client.userId = undefined;
|
|
23623
|
+
client.token = undefined;
|
|
23624
|
+
client.loginType = undefined;
|
|
23625
|
+
client.http.defaults.headers.common.Authorization = '';
|
|
23626
|
+
client.http.defaults.metadata = {
|
|
23627
|
+
tokenExpiry: '',
|
|
23628
|
+
isGlobalBanned: false,
|
|
23629
|
+
isUserDeleted: false,
|
|
23630
|
+
};
|
|
23631
|
+
if (typeof document !== 'undefined') {
|
|
23632
|
+
document.cookie = '_ascSession=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
|
23633
|
+
}
|
|
23634
|
+
/*
|
|
23635
|
+
* Cache should be usable if tokenExpired
|
|
23636
|
+
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#SDK-usability-based-on-Session-State
|
|
23637
|
+
*/
|
|
23638
|
+
if (client.sessionState !== "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.cache) {
|
|
23639
|
+
client.cache = { data: {} };
|
|
23640
|
+
}
|
|
23641
|
+
return true;
|
|
23642
|
+
};
|
|
23643
|
+
/* end_public_function */
|
|
23644
|
+
|
|
23645
|
+
/**
|
|
23646
|
+
* Terminates {@link Amity.Client} instance
|
|
23647
|
+
*
|
|
23648
|
+
*
|
|
23649
|
+
*
|
|
23650
|
+
* @category private
|
|
23651
|
+
*/
|
|
23652
|
+
const terminateClient = (terminationReason) => {
|
|
23653
|
+
const client = getActiveClient();
|
|
23654
|
+
setSessionState("terminated" /* Amity.SessionStates.TERMINATED */, terminationReason);
|
|
23655
|
+
if (client.http.defaults.metadata) {
|
|
23656
|
+
if (terminationReason === "globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */)
|
|
23657
|
+
client.http.defaults.metadata.isGlobalBanned = true;
|
|
23658
|
+
if (terminationReason === "userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */)
|
|
23659
|
+
client.http.defaults.metadata.isUserDeleted = true;
|
|
23660
|
+
}
|
|
23661
|
+
client.sessionHandler = undefined;
|
|
23662
|
+
logout();
|
|
23663
|
+
};
|
|
23664
|
+
|
|
23665
|
+
let currentUserType = null;
|
|
23666
|
+
/* begin_public_function
|
|
23667
|
+
id: client.get_current_user_type
|
|
23668
|
+
*/
|
|
23669
|
+
const getCurrentUserType = () => {
|
|
23670
|
+
if (!currentUserType) {
|
|
23671
|
+
throw new ASCError('Connect client first', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
|
|
23672
|
+
}
|
|
23673
|
+
return currentUserType;
|
|
23674
|
+
};
|
|
23675
|
+
/* end_public_function */
|
|
23676
|
+
const setCurrentUserType = (userType) => {
|
|
23677
|
+
currentUserType = userType;
|
|
23678
|
+
};
|
|
23679
|
+
|
|
23680
|
+
const setCurrentUser = ({ user, userType, }) => {
|
|
23681
|
+
setActiveUser(user);
|
|
23682
|
+
setCurrentUserType(userType);
|
|
23683
|
+
};
|
|
23684
|
+
|
|
23573
23685
|
const createUserEventSubscriber = (event, callback) => {
|
|
23574
23686
|
const client = getActiveClient();
|
|
23575
23687
|
const filter = (data) => {
|
|
@@ -23888,13 +24000,13 @@ class AnalyticsEngine {
|
|
|
23888
24000
|
this._eventCapturer.resetAllBuckets();
|
|
23889
24001
|
}
|
|
23890
24002
|
}
|
|
23891
|
-
let instance$
|
|
24003
|
+
let instance$6;
|
|
23892
24004
|
var AnalyticsEngine$1 = {
|
|
23893
24005
|
getInstance: () => {
|
|
23894
|
-
if (!instance$
|
|
23895
|
-
instance$
|
|
24006
|
+
if (!instance$6) {
|
|
24007
|
+
instance$6 = new AnalyticsEngine();
|
|
23896
24008
|
}
|
|
23897
|
-
return instance$
|
|
24009
|
+
return instance$6;
|
|
23898
24010
|
},
|
|
23899
24011
|
};
|
|
23900
24012
|
|
|
@@ -24122,12 +24234,12 @@ class MessageReadReceiptSyncEngine {
|
|
|
24122
24234
|
}
|
|
24123
24235
|
}
|
|
24124
24236
|
}
|
|
24125
|
-
let instance$
|
|
24237
|
+
let instance$5 = null;
|
|
24126
24238
|
var ReadReceiptSyncEngine = {
|
|
24127
24239
|
getInstance: () => {
|
|
24128
|
-
if (!instance$
|
|
24129
|
-
instance$
|
|
24130
|
-
return instance$
|
|
24240
|
+
if (!instance$5)
|
|
24241
|
+
instance$5 = new MessageReadReceiptSyncEngine();
|
|
24242
|
+
return instance$5;
|
|
24131
24243
|
},
|
|
24132
24244
|
};
|
|
24133
24245
|
|
|
@@ -24381,12 +24493,12 @@ class LegacyMessageReadReceiptSyncEngine {
|
|
|
24381
24493
|
}
|
|
24382
24494
|
}
|
|
24383
24495
|
}
|
|
24384
|
-
let instance$
|
|
24496
|
+
let instance$4 = null;
|
|
24385
24497
|
var LegacyReadReceiptSyncEngine = {
|
|
24386
24498
|
getInstance: () => {
|
|
24387
|
-
if (!instance$
|
|
24388
|
-
instance$
|
|
24389
|
-
return instance$
|
|
24499
|
+
if (!instance$4)
|
|
24500
|
+
instance$4 = new LegacyMessageReadReceiptSyncEngine();
|
|
24501
|
+
return instance$4;
|
|
24390
24502
|
},
|
|
24391
24503
|
};
|
|
24392
24504
|
|
|
@@ -24662,12 +24774,12 @@ class ObjectResolverEngine {
|
|
|
24662
24774
|
this.stopResolver();
|
|
24663
24775
|
}
|
|
24664
24776
|
}
|
|
24665
|
-
let instance$
|
|
24777
|
+
let instance$3 = null;
|
|
24666
24778
|
var ObjectResolverEngine$1 = {
|
|
24667
24779
|
getInstance: () => {
|
|
24668
|
-
if (!instance$
|
|
24669
|
-
instance$
|
|
24670
|
-
return instance$
|
|
24780
|
+
if (!instance$3)
|
|
24781
|
+
instance$3 = new ObjectResolverEngine();
|
|
24782
|
+
return instance$3;
|
|
24671
24783
|
},
|
|
24672
24784
|
};
|
|
24673
24785
|
|
|
@@ -24817,13 +24929,13 @@ class LiveReactionSyncEngine {
|
|
|
24817
24929
|
this.stopReactionsSync();
|
|
24818
24930
|
}
|
|
24819
24931
|
}
|
|
24820
|
-
let instance$
|
|
24932
|
+
let instance$2;
|
|
24821
24933
|
var ReactionSyncEngine = {
|
|
24822
24934
|
getInstance: () => {
|
|
24823
|
-
if (!instance$
|
|
24824
|
-
instance$
|
|
24935
|
+
if (!instance$2) {
|
|
24936
|
+
instance$2 = new LiveReactionSyncEngine();
|
|
24825
24937
|
}
|
|
24826
|
-
return instance$
|
|
24938
|
+
return instance$2;
|
|
24827
24939
|
},
|
|
24828
24940
|
};
|
|
24829
24941
|
|
|
@@ -24845,87 +24957,6 @@ var reactionSyncEngineOnLoginHandler = () => {
|
|
|
24845
24957
|
};
|
|
24846
24958
|
};
|
|
24847
24959
|
|
|
24848
|
-
/* begin_public_function
|
|
24849
|
-
id: client.logout
|
|
24850
|
-
*/
|
|
24851
|
-
/**
|
|
24852
|
-
* ```js
|
|
24853
|
-
* import { Client } from '@amityco/ts-sdk-react-native';
|
|
24854
|
-
* const success = await Client.logout()
|
|
24855
|
-
* ```
|
|
24856
|
-
*
|
|
24857
|
-
* Disconnects an {@link Amity.Client} instance from ASC servers
|
|
24858
|
-
*
|
|
24859
|
-
* @returns a success boolean if disconnected
|
|
24860
|
-
*
|
|
24861
|
-
* @category Client API
|
|
24862
|
-
* @async
|
|
24863
|
-
*/
|
|
24864
|
-
const logout = async () => {
|
|
24865
|
-
var _a;
|
|
24866
|
-
const client = getActiveClient();
|
|
24867
|
-
client.log('client/api/disconnectClient');
|
|
24868
|
-
if (client.mqtt && client.mqtt.connected) {
|
|
24869
|
-
client.mqtt.disconnect();
|
|
24870
|
-
}
|
|
24871
|
-
/*
|
|
24872
|
-
* for cases when session state is terminated (example on ban) or token expired,
|
|
24873
|
-
* the terminating block will set session state to terminated or for the or
|
|
24874
|
-
* in the case of expired token the same happens
|
|
24875
|
-
*
|
|
24876
|
-
* establishing state also ignored in cases where accessTokenExpiryWatcher
|
|
24877
|
-
* calls renewal. There is a possibility that renewal will be called before
|
|
24878
|
-
* disconnectClient finishes execution
|
|
24879
|
-
*
|
|
24880
|
-
* IMPORTANT: call this before `emitter.all.clear()`, otherwise the session
|
|
24881
|
-
* event will never be triggered
|
|
24882
|
-
*/
|
|
24883
|
-
if (client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */)
|
|
24884
|
-
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
24885
|
-
client.emitter.all.clear();
|
|
24886
|
-
(_a = client.mqtt) === null || _a === void 0 ? void 0 : _a.removeAllListeners();
|
|
24887
|
-
client.userId = undefined;
|
|
24888
|
-
client.token = undefined;
|
|
24889
|
-
client.http.defaults.headers.common.Authorization = '';
|
|
24890
|
-
client.http.defaults.metadata = {
|
|
24891
|
-
tokenExpiry: '',
|
|
24892
|
-
isGlobalBanned: false,
|
|
24893
|
-
isUserDeleted: false,
|
|
24894
|
-
};
|
|
24895
|
-
if (typeof document !== 'undefined') {
|
|
24896
|
-
document.cookie = '_ascSession=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
|
24897
|
-
}
|
|
24898
|
-
/*
|
|
24899
|
-
* Cache should be usable if tokenExpired
|
|
24900
|
-
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#SDK-usability-based-on-Session-State
|
|
24901
|
-
*/
|
|
24902
|
-
if (client.sessionState !== "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.cache) {
|
|
24903
|
-
client.cache = { data: {} };
|
|
24904
|
-
}
|
|
24905
|
-
return true;
|
|
24906
|
-
};
|
|
24907
|
-
/* end_public_function */
|
|
24908
|
-
|
|
24909
|
-
/**
|
|
24910
|
-
* Terminates {@link Amity.Client} instance
|
|
24911
|
-
*
|
|
24912
|
-
*
|
|
24913
|
-
*
|
|
24914
|
-
* @category private
|
|
24915
|
-
*/
|
|
24916
|
-
const terminateClient = (terminationReason) => {
|
|
24917
|
-
const client = getActiveClient();
|
|
24918
|
-
setSessionState("terminated" /* Amity.SessionStates.TERMINATED */, terminationReason);
|
|
24919
|
-
if (client.http.defaults.metadata) {
|
|
24920
|
-
if (terminationReason === "globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */)
|
|
24921
|
-
client.http.defaults.metadata.isGlobalBanned = true;
|
|
24922
|
-
if (terminationReason === "userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */)
|
|
24923
|
-
client.http.defaults.metadata.isUserDeleted = true;
|
|
24924
|
-
}
|
|
24925
|
-
client.sessionHandler = undefined;
|
|
24926
|
-
logout();
|
|
24927
|
-
};
|
|
24928
|
-
|
|
24929
24960
|
const EVENTS = [
|
|
24930
24961
|
'disconnected',
|
|
24931
24962
|
'error',
|
|
@@ -25055,24 +25086,50 @@ const removeChannelMarkerCache = (channel) => {
|
|
|
25055
25086
|
dropFromCache(['channelMarker', 'get', id], true);
|
|
25056
25087
|
};
|
|
25057
25088
|
|
|
25058
|
-
|
|
25059
|
-
|
|
25060
|
-
|
|
25061
|
-
|
|
25062
|
-
|
|
25063
|
-
|
|
25064
|
-
|
|
25089
|
+
/**
|
|
25090
|
+
* Sets up all login-related event subscriptions
|
|
25091
|
+
* This includes handlers for user bans, deletions, token events, and various engine initializations
|
|
25092
|
+
*
|
|
25093
|
+
* @param unsubWatcher - The unsubscriber function for the access token expiry watcher
|
|
25094
|
+
* @returns Array of unsubscriber functions for all registered subscriptions
|
|
25095
|
+
*
|
|
25096
|
+
* @category private
|
|
25097
|
+
*/
|
|
25098
|
+
const setupLoginSubscriptions = (unsubWatcher) => {
|
|
25099
|
+
const client = getActiveClient();
|
|
25100
|
+
const subscriptions = [];
|
|
25101
|
+
subscriptions.push(
|
|
25102
|
+
// GLOBAL_BAN
|
|
25103
|
+
onClientBanned((_) => {
|
|
25104
|
+
terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
|
|
25105
|
+
subscriptions.forEach(fn => fn());
|
|
25106
|
+
unsubWatcher();
|
|
25107
|
+
}), onTokenTerminated(_ => {
|
|
25108
|
+
terminateClient();
|
|
25109
|
+
subscriptions.forEach(fn => fn());
|
|
25110
|
+
unsubWatcher();
|
|
25111
|
+
}), onUserDeleted$2((user) => {
|
|
25112
|
+
if (user.userId === client.userId) {
|
|
25113
|
+
terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
|
|
25114
|
+
subscriptions.forEach(fn => fn());
|
|
25115
|
+
unsubWatcher();
|
|
25116
|
+
}
|
|
25117
|
+
}), onTokenExpired(state => {
|
|
25118
|
+
SessionWatcher$1.getInstance().setSessionState(state);
|
|
25119
|
+
logout();
|
|
25120
|
+
subscriptions.forEach(fn => fn());
|
|
25121
|
+
}),
|
|
25122
|
+
// NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
|
|
25123
|
+
// the channel because currently backend can't handle this, so every time a user is banned from
|
|
25124
|
+
// a channel or the channel is deleted the channel's unread count will not be reset to zero
|
|
25125
|
+
onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler());
|
|
25126
|
+
if (client.useLegacyUnreadCount) {
|
|
25127
|
+
subscriptions.push(readReceiptSyncEngineOnLoginHandler());
|
|
25065
25128
|
}
|
|
25066
|
-
|
|
25067
|
-
|
|
25068
|
-
|
|
25069
|
-
|
|
25070
|
-
currentUserType = userType;
|
|
25071
|
-
};
|
|
25072
|
-
|
|
25073
|
-
const setCurrentUser = ({ user, userType, }) => {
|
|
25074
|
-
setActiveUser(user);
|
|
25075
|
-
setCurrentUserType(userType);
|
|
25129
|
+
else {
|
|
25130
|
+
subscriptions.push(legacyReadReceiptSyncEngineOnLoginHandler());
|
|
25131
|
+
}
|
|
25132
|
+
return subscriptions;
|
|
25076
25133
|
};
|
|
25077
25134
|
|
|
25078
25135
|
/* eslint-disable no-param-reassign */
|
|
@@ -25081,8 +25138,8 @@ const setCurrentUser = ({ user, userType, }) => {
|
|
|
25081
25138
|
* than the one already connected, in which case the existing subscriptions need
|
|
25082
25139
|
* to be cleared
|
|
25083
25140
|
*/
|
|
25084
|
-
let subscriptions$
|
|
25085
|
-
async function runMqtt$
|
|
25141
|
+
let subscriptions$4 = [];
|
|
25142
|
+
async function runMqtt$2() {
|
|
25086
25143
|
await modifyMqttConnection();
|
|
25087
25144
|
}
|
|
25088
25145
|
/* begin_public_function
|
|
@@ -25116,8 +25173,8 @@ const login = async (params, sessionHandler, config) => {
|
|
|
25116
25173
|
if (client.userId && client.userId !== params.userId) {
|
|
25117
25174
|
await logout();
|
|
25118
25175
|
// Remove subscription to ban and delete
|
|
25119
|
-
subscriptions$
|
|
25120
|
-
subscriptions$
|
|
25176
|
+
subscriptions$4.forEach(fn => fn());
|
|
25177
|
+
subscriptions$4 = [];
|
|
25121
25178
|
}
|
|
25122
25179
|
// default values
|
|
25123
25180
|
const defaultDeviceId = await getDeviceId();
|
|
@@ -25142,11 +25199,12 @@ const login = async (params, sessionHandler, config) => {
|
|
|
25142
25199
|
}
|
|
25143
25200
|
client.userId = user.userId;
|
|
25144
25201
|
client.sessionHandler = sessionHandler;
|
|
25202
|
+
client.loginType = 'userId';
|
|
25145
25203
|
/*
|
|
25146
25204
|
* Cannot push to subscriptions as watcher needs to continue working even if
|
|
25147
25205
|
* token expires
|
|
25148
25206
|
*/
|
|
25149
|
-
unsubWatcher = client.accessTokenExpiryWatcher(
|
|
25207
|
+
unsubWatcher = client.accessTokenExpiryWatcher();
|
|
25150
25208
|
setCurrentUser({ user, userType });
|
|
25151
25209
|
}
|
|
25152
25210
|
catch (error) {
|
|
@@ -25159,40 +25217,11 @@ const login = async (params, sessionHandler, config) => {
|
|
|
25159
25217
|
throw error;
|
|
25160
25218
|
}
|
|
25161
25219
|
if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
|
|
25162
|
-
runMqtt$
|
|
25220
|
+
runMqtt$2();
|
|
25163
25221
|
}
|
|
25164
25222
|
await initializeMessagePreviewSetting();
|
|
25165
|
-
if (subscriptions$
|
|
25166
|
-
subscriptions$
|
|
25167
|
-
// GLOBAL_BAN
|
|
25168
|
-
onClientBanned((_) => {
|
|
25169
|
-
terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
|
|
25170
|
-
subscriptions$3.forEach(fn => fn());
|
|
25171
|
-
unsubWatcher();
|
|
25172
|
-
}), onTokenTerminated(_ => {
|
|
25173
|
-
terminateClient();
|
|
25174
|
-
subscriptions$3.forEach(fn => fn());
|
|
25175
|
-
unsubWatcher();
|
|
25176
|
-
}), onUserDeleted$2((user) => {
|
|
25177
|
-
if (user.userId === client.userId) {
|
|
25178
|
-
terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
|
|
25179
|
-
subscriptions$3.forEach(fn => fn());
|
|
25180
|
-
unsubWatcher();
|
|
25181
|
-
}
|
|
25182
|
-
}), onTokenExpired(state => {
|
|
25183
|
-
SessionWatcher$1.getInstance().setSessionState(state);
|
|
25184
|
-
logout();
|
|
25185
|
-
subscriptions$3.forEach(fn => fn());
|
|
25186
|
-
}),
|
|
25187
|
-
// NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
|
|
25188
|
-
// the channel because currently backend can't handle this, so every time a user is banned from
|
|
25189
|
-
// a channel or the channel is deleted the channel's unread count will not be reset to zero
|
|
25190
|
-
onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler());
|
|
25191
|
-
if (client.useLegacyUnreadCount) {
|
|
25192
|
-
subscriptions$3.push(readReceiptSyncEngineOnLoginHandler());
|
|
25193
|
-
}
|
|
25194
|
-
else
|
|
25195
|
-
subscriptions$3.push(legacyReadReceiptSyncEngineOnLoginHandler());
|
|
25223
|
+
if (subscriptions$4.length === 0) {
|
|
25224
|
+
subscriptions$4 = setupLoginSubscriptions(unsubWatcher);
|
|
25196
25225
|
}
|
|
25197
25226
|
return true;
|
|
25198
25227
|
};
|
|
@@ -25204,7 +25233,7 @@ const login = async (params, sessionHandler, config) => {
|
|
|
25204
25233
|
* than the one already connected, in which case the existing subscriptions need
|
|
25205
25234
|
* to be cleared
|
|
25206
25235
|
*/
|
|
25207
|
-
const subscriptions$
|
|
25236
|
+
const subscriptions$3 = [];
|
|
25208
25237
|
/* begin_public_function
|
|
25209
25238
|
id: client.loginAsVisitor
|
|
25210
25239
|
*/
|
|
@@ -25247,11 +25276,12 @@ const loginAsVisitor = async (params) => {
|
|
|
25247
25276
|
[user] = users;
|
|
25248
25277
|
client.userId = user.userId;
|
|
25249
25278
|
client.sessionHandler = params.sessionHandler;
|
|
25279
|
+
client.loginType = 'userId';
|
|
25250
25280
|
/*
|
|
25251
25281
|
* Cannot push to subscriptions as watcher needs to continue working even if
|
|
25252
25282
|
* token expires
|
|
25253
25283
|
*/
|
|
25254
|
-
unsubWatcher = client.accessTokenExpiryWatcher(
|
|
25284
|
+
unsubWatcher = client.accessTokenExpiryWatcher();
|
|
25255
25285
|
setCurrentUser({ user, userType });
|
|
25256
25286
|
}
|
|
25257
25287
|
catch (error) {
|
|
@@ -25264,16 +25294,16 @@ const loginAsVisitor = async (params) => {
|
|
|
25264
25294
|
throw error;
|
|
25265
25295
|
}
|
|
25266
25296
|
await initializeMessagePreviewSetting();
|
|
25267
|
-
if (subscriptions$
|
|
25297
|
+
if (subscriptions$3.length === 0) {
|
|
25268
25298
|
// handling internal SDK events
|
|
25269
|
-
subscriptions$
|
|
25299
|
+
subscriptions$3.push(onTokenTerminated(_ => {
|
|
25270
25300
|
terminateClient();
|
|
25271
|
-
subscriptions$
|
|
25301
|
+
subscriptions$3.forEach(fn => fn());
|
|
25272
25302
|
unsubWatcher();
|
|
25273
25303
|
}), onTokenExpired(state => {
|
|
25274
25304
|
SessionWatcher$1.getInstance().setSessionState(state);
|
|
25275
25305
|
logout();
|
|
25276
|
-
subscriptions$
|
|
25306
|
+
subscriptions$3.forEach(fn => fn());
|
|
25277
25307
|
}));
|
|
25278
25308
|
}
|
|
25279
25309
|
return true;
|
|
@@ -25302,7 +25332,7 @@ const renewal = () => {
|
|
|
25302
25332
|
* Per instance of Renewal, only one renewal is allowed
|
|
25303
25333
|
*/
|
|
25304
25334
|
const renewToken = async (authToken) => {
|
|
25305
|
-
const { userId, displayName } =
|
|
25335
|
+
const { userId, displayName } = getActiveUser();
|
|
25306
25336
|
const deviceId = await getDeviceId();
|
|
25307
25337
|
const params = { userId, displayName, authToken, deviceId };
|
|
25308
25338
|
if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.sessionHandler) {
|
|
@@ -25377,6 +25407,242 @@ const renewal = () => {
|
|
|
25377
25407
|
};
|
|
25378
25408
|
/* end_public_function */
|
|
25379
25409
|
|
|
25410
|
+
const validateAccessToken = async ({ token, userId }) => {
|
|
25411
|
+
const client = getActiveClient();
|
|
25412
|
+
// Validate token using sessions API
|
|
25413
|
+
await client.http.get('/api/v3/sessions', {
|
|
25414
|
+
headers: {
|
|
25415
|
+
Authorization: `Bearer ${token.accessToken}`,
|
|
25416
|
+
},
|
|
25417
|
+
});
|
|
25418
|
+
// Get user details
|
|
25419
|
+
const { data: { users }, } = await client.http.get(`/api/v3/users/${userId}`, {
|
|
25420
|
+
headers: {
|
|
25421
|
+
Authorization: `Bearer ${token.accessToken}`,
|
|
25422
|
+
},
|
|
25423
|
+
});
|
|
25424
|
+
const user = users.find((u) => u.userId === userId);
|
|
25425
|
+
client.http.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
|
|
25426
|
+
client.http.defaults.metadata = {
|
|
25427
|
+
tokenExpiry: token.expiresAt,
|
|
25428
|
+
isGlobalBanned: false,
|
|
25429
|
+
isUserDeleted: false,
|
|
25430
|
+
};
|
|
25431
|
+
client.upload.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
|
|
25432
|
+
client.upload.defaults.metadata = {
|
|
25433
|
+
tokenExpiry: token.expiresAt,
|
|
25434
|
+
isGlobalBanned: false,
|
|
25435
|
+
isUserDeleted: false,
|
|
25436
|
+
};
|
|
25437
|
+
client.token = token;
|
|
25438
|
+
return user;
|
|
25439
|
+
};
|
|
25440
|
+
|
|
25441
|
+
const isSameUserId = (token) => {
|
|
25442
|
+
var _a;
|
|
25443
|
+
const client = getActiveClient();
|
|
25444
|
+
const decoded = jwtDecode(token);
|
|
25445
|
+
return ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) === client.userId;
|
|
25446
|
+
};
|
|
25447
|
+
|
|
25448
|
+
let subscriptions$2 = [];
|
|
25449
|
+
async function runMqtt$1() {
|
|
25450
|
+
await modifyMqttConnection();
|
|
25451
|
+
}
|
|
25452
|
+
/* begin_public_function
|
|
25453
|
+
id: client.loginWithAccessToken
|
|
25454
|
+
*/
|
|
25455
|
+
/**
|
|
25456
|
+
* ```js
|
|
25457
|
+
* import { loginWithAccessToken } from '@amityco/ts-sdk'
|
|
25458
|
+
* const success = await loginWithAccessToken('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...')
|
|
25459
|
+
* ```
|
|
25460
|
+
*
|
|
25461
|
+
* Authenticates a user using a pre-existing access token, allowing direct login without user credentials.
|
|
25462
|
+
* Designed for customers who manage access tokens on their own backend.
|
|
25463
|
+
*
|
|
25464
|
+
* @param accessToken JWT access token signed by customer's backend containing user identity
|
|
25465
|
+
* @returns true if authentication is successful
|
|
25466
|
+
*
|
|
25467
|
+
* @category Client API
|
|
25468
|
+
* @async
|
|
25469
|
+
*/
|
|
25470
|
+
const loginWithAccessToken = async (accessToken) => {
|
|
25471
|
+
var _a, _b;
|
|
25472
|
+
const client = getActiveClient();
|
|
25473
|
+
let unsubWatcher;
|
|
25474
|
+
client.log('client/api/loginWithAccessToken', {
|
|
25475
|
+
apiKey: client.apiKey,
|
|
25476
|
+
sessionState: client.sessionState,
|
|
25477
|
+
});
|
|
25478
|
+
// Validate input
|
|
25479
|
+
if (!accessToken || typeof accessToken !== 'string' || accessToken.trim() === '') {
|
|
25480
|
+
throw new ASCError('Access token must be a non-empty string', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
25481
|
+
}
|
|
25482
|
+
let decoded;
|
|
25483
|
+
try {
|
|
25484
|
+
decoded = jwtDecode(accessToken);
|
|
25485
|
+
}
|
|
25486
|
+
catch (error) {
|
|
25487
|
+
throw new ASCError('Invalid access token format', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
25488
|
+
}
|
|
25489
|
+
// Extract userId from token
|
|
25490
|
+
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);
|
|
25491
|
+
if (!userId) {
|
|
25492
|
+
throw new ASCError('Access token does not contain userId', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
25493
|
+
}
|
|
25494
|
+
// Handle existing connected user
|
|
25495
|
+
if (client.userId) {
|
|
25496
|
+
const sameUser = isSameUserId(accessToken);
|
|
25497
|
+
if (!sameUser) {
|
|
25498
|
+
// Different user - do full logout
|
|
25499
|
+
await logout();
|
|
25500
|
+
}
|
|
25501
|
+
}
|
|
25502
|
+
try {
|
|
25503
|
+
// Set state to establishing
|
|
25504
|
+
setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
|
|
25505
|
+
// Prepare token object for validation
|
|
25506
|
+
const tokenObject = {
|
|
25507
|
+
accessToken,
|
|
25508
|
+
issuedAt: decoded.iat ? new Date(decoded.iat * 1000).toISOString() : new Date().toISOString(),
|
|
25509
|
+
expiresAt: new Date(decoded.exp * 1000).toISOString(),
|
|
25510
|
+
};
|
|
25511
|
+
// Validate token and get user
|
|
25512
|
+
const user = await validateAccessToken({
|
|
25513
|
+
token: tokenObject,
|
|
25514
|
+
userId,
|
|
25515
|
+
});
|
|
25516
|
+
if (user == null) {
|
|
25517
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
25518
|
+
throw new ASCError(`User ${userId} has not been found`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
25519
|
+
}
|
|
25520
|
+
if (user.isDeleted) {
|
|
25521
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
25522
|
+
throw new ASCError(`User ${userId} has been deleted`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
25523
|
+
}
|
|
25524
|
+
if (user.isGlobalBanned) {
|
|
25525
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
25526
|
+
throw new ASCError(`User ${userId} is globally banned`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
25527
|
+
}
|
|
25528
|
+
// Set userId and login method flag
|
|
25529
|
+
client.userId = user.userId;
|
|
25530
|
+
// Set login method flag to 'accessToken' in platform-specific login session
|
|
25531
|
+
client.loginType = 'accessToken';
|
|
25532
|
+
// This will be used by the access token handler to determine if token renewal should be invoked
|
|
25533
|
+
// Set active user
|
|
25534
|
+
setActiveUser(user);
|
|
25535
|
+
unsubWatcher = client.accessTokenExpiryWatcher();
|
|
25536
|
+
setSessionState("established" /* Amity.SessionStates.ESTABLISHED */);
|
|
25537
|
+
}
|
|
25538
|
+
catch (error) {
|
|
25539
|
+
// If error occurs, revert session state to not logged in
|
|
25540
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
25541
|
+
// Re-throw if it's already an ASCError
|
|
25542
|
+
if (error instanceof ASCError) {
|
|
25543
|
+
throw error;
|
|
25544
|
+
}
|
|
25545
|
+
// Wrap other errors
|
|
25546
|
+
throw new ASCError((error instanceof Error ? error.message : undefined) || 'Login with access token failed', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
25547
|
+
}
|
|
25548
|
+
runMqtt$1();
|
|
25549
|
+
await initializeMessagePreviewSetting();
|
|
25550
|
+
if (subscriptions$2.length === 0) {
|
|
25551
|
+
subscriptions$2 = setupLoginSubscriptions(unsubWatcher);
|
|
25552
|
+
}
|
|
25553
|
+
return true;
|
|
25554
|
+
};
|
|
25555
|
+
/* end_public_function */
|
|
25556
|
+
|
|
25557
|
+
/* begin_public_function
|
|
25558
|
+
id: client.renew_with_accessToken
|
|
25559
|
+
*/
|
|
25560
|
+
/*
|
|
25561
|
+
* Renewal defintion accepted by SessionHandler interface
|
|
25562
|
+
*
|
|
25563
|
+
* Tech Spec:
|
|
25564
|
+
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Session-Handler
|
|
25565
|
+
*
|
|
25566
|
+
* @category private
|
|
25567
|
+
*/
|
|
25568
|
+
const renewWithAccessToken = async (accessToken) => {
|
|
25569
|
+
var _a, _b;
|
|
25570
|
+
const client = getActiveClient();
|
|
25571
|
+
client.log('initiating access token renewal');
|
|
25572
|
+
/*
|
|
25573
|
+
* Renews a token if it is hasn't been renewed before. Also marks token as
|
|
25574
|
+
* renewed once done
|
|
25575
|
+
* Per instance of Renewal, only one renewal is allowed
|
|
25576
|
+
*/
|
|
25577
|
+
// Validate input
|
|
25578
|
+
if (!accessToken || typeof accessToken !== 'string' || accessToken.trim() === '') {
|
|
25579
|
+
throw new ASCError('Access token must be a non-empty string', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
25580
|
+
}
|
|
25581
|
+
let decoded;
|
|
25582
|
+
try {
|
|
25583
|
+
decoded = jwtDecode(accessToken);
|
|
25584
|
+
}
|
|
25585
|
+
catch (error) {
|
|
25586
|
+
throw new ASCError('Invalid access token format', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
25587
|
+
}
|
|
25588
|
+
// Extract userId from token
|
|
25589
|
+
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);
|
|
25590
|
+
if (!userId) {
|
|
25591
|
+
throw new ASCError('Access token does not contain userId', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
25592
|
+
}
|
|
25593
|
+
// Handle existing connected user
|
|
25594
|
+
if (client.userId) {
|
|
25595
|
+
const sameUser = isSameUserId(accessToken);
|
|
25596
|
+
if (!sameUser) {
|
|
25597
|
+
// Different user - do full logout
|
|
25598
|
+
await logout();
|
|
25599
|
+
}
|
|
25600
|
+
}
|
|
25601
|
+
const tokenObject = {
|
|
25602
|
+
accessToken,
|
|
25603
|
+
issuedAt: decoded.iat ? new Date(decoded.iat * 1000).toISOString() : new Date().toISOString(),
|
|
25604
|
+
expiresAt: new Date(decoded.exp * 1000).toISOString(),
|
|
25605
|
+
};
|
|
25606
|
+
if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.sessionHandler) {
|
|
25607
|
+
await loginWithAccessToken(accessToken);
|
|
25608
|
+
}
|
|
25609
|
+
else {
|
|
25610
|
+
// about to expire
|
|
25611
|
+
await validateAccessToken({
|
|
25612
|
+
token: tokenObject,
|
|
25613
|
+
userId,
|
|
25614
|
+
});
|
|
25615
|
+
}
|
|
25616
|
+
};
|
|
25617
|
+
/* end_public_function */
|
|
25618
|
+
|
|
25619
|
+
/**
|
|
25620
|
+
* Helper function to renew access token using the accessTokenHandler
|
|
25621
|
+
* Handles error catching and logging
|
|
25622
|
+
*
|
|
25623
|
+
* @param useScheduledTask - Whether to wrap renewal in scheduleTask (for token expired case)
|
|
25624
|
+
* @category private
|
|
25625
|
+
*/
|
|
25626
|
+
const renewTokenWithHandler = async ({ useScheduledTask = false, }) => {
|
|
25627
|
+
const client = getActiveClient();
|
|
25628
|
+
if (!client.userId || !client.accessTokenHandler) {
|
|
25629
|
+
return;
|
|
25630
|
+
}
|
|
25631
|
+
try {
|
|
25632
|
+
const newToken = await client.accessTokenHandler.onTokenRenew(client.userId);
|
|
25633
|
+
if (useScheduledTask) {
|
|
25634
|
+
scheduleTask(() => renewWithAccessToken(newToken));
|
|
25635
|
+
}
|
|
25636
|
+
else {
|
|
25637
|
+
renewWithAccessToken(newToken);
|
|
25638
|
+
}
|
|
25639
|
+
}
|
|
25640
|
+
catch (error) {
|
|
25641
|
+
client.log('Proactive token renewal failed, will retry when token expires', error);
|
|
25642
|
+
// Will fallback to expired token flow
|
|
25643
|
+
}
|
|
25644
|
+
};
|
|
25645
|
+
|
|
25380
25646
|
const ABOUT_TO_EXPIRE_THRESHOLD = 80 / 100;
|
|
25381
25647
|
const COMPENSATED_DELAY = 5 * MINUTE;
|
|
25382
25648
|
/*
|
|
@@ -25412,10 +25678,11 @@ const isAboutToExpire = (params) => {
|
|
|
25412
25678
|
*
|
|
25413
25679
|
* @category private
|
|
25414
25680
|
*/
|
|
25415
|
-
const accessTokenExpiryWatcher = (
|
|
25416
|
-
const interval = setInterval(() => {
|
|
25681
|
+
const accessTokenExpiryWatcher = () => {
|
|
25682
|
+
const interval = setInterval(async () => {
|
|
25417
25683
|
const client = getActiveClient();
|
|
25418
|
-
|
|
25684
|
+
const { sessionHandler, accessTokenHandler, loginType } = client;
|
|
25685
|
+
if (!client.token || !client.userId)
|
|
25419
25686
|
return;
|
|
25420
25687
|
const { issuedAt, expiresAt } = client.token;
|
|
25421
25688
|
if (isExpired(expiresAt)) {
|
|
@@ -25426,18 +25693,38 @@ const accessTokenExpiryWatcher = (sessionHandler) => {
|
|
|
25426
25693
|
*/
|
|
25427
25694
|
fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
|
|
25428
25695
|
/*
|
|
25429
|
-
*
|
|
25430
|
-
*
|
|
25431
|
-
*
|
|
25432
|
-
* Since fireEvent is scheduled, it will be called
|
|
25433
|
-
* after sessionHandler leading to an invalid state change from
|
|
25434
|
-
* establishing to tokenExpired
|
|
25696
|
+
* Check loginType to determine which handler to use:
|
|
25697
|
+
* - 'accessToken' = use accessTokenHandler
|
|
25698
|
+
* - 'userId' = use sessionHandler
|
|
25435
25699
|
*/
|
|
25436
|
-
|
|
25700
|
+
if (loginType === 'accessToken' && accessTokenHandler) {
|
|
25701
|
+
await renewTokenWithHandler({ useScheduledTask: false });
|
|
25702
|
+
}
|
|
25703
|
+
else if (loginType === 'userId' && sessionHandler) {
|
|
25704
|
+
/*
|
|
25705
|
+
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Automatically-initiate-renewal-flow
|
|
25706
|
+
*
|
|
25707
|
+
* Why scheduled task?
|
|
25708
|
+
* Since fireEvent is scheduled, it will be called
|
|
25709
|
+
* after sessionHandler leading to an invalid state change from
|
|
25710
|
+
* establishing to tokenExpired
|
|
25711
|
+
*/
|
|
25712
|
+
scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
|
|
25713
|
+
}
|
|
25437
25714
|
return;
|
|
25438
25715
|
}
|
|
25439
25716
|
if (isAboutToExpire({ expiresAt, issuedAt })) {
|
|
25440
|
-
|
|
25717
|
+
/*
|
|
25718
|
+
* Check loginType to determine which handler to use for proactive renewal:
|
|
25719
|
+
* - 'accessToken' = use accessTokenHandler
|
|
25720
|
+
* - 'userId' = use sessionHandler
|
|
25721
|
+
*/
|
|
25722
|
+
if (loginType === 'accessToken' && accessTokenHandler) {
|
|
25723
|
+
await renewTokenWithHandler({ useScheduledTask: false });
|
|
25724
|
+
}
|
|
25725
|
+
else if (loginType === 'userId' && sessionHandler) {
|
|
25726
|
+
sessionHandler.sessionWillRenewAccessToken(renewal());
|
|
25727
|
+
}
|
|
25441
25728
|
}
|
|
25442
25729
|
}, ACCESS_TOKEN_WATCHER_INTERVAL);
|
|
25443
25730
|
return () => clearInterval(interval);
|
|
@@ -25991,6 +26278,7 @@ const secureLogout = async () => {
|
|
|
25991
26278
|
};
|
|
25992
26279
|
/* end_public_function */
|
|
25993
26280
|
|
|
26281
|
+
/* eslint-disable no-param-reassign */
|
|
25994
26282
|
/*
|
|
25995
26283
|
* declared earlier to accomodate case when logging in with a different user
|
|
25996
26284
|
* than the one already connected, in which case the existing subscriptions need
|
|
@@ -26000,38 +26288,6 @@ let subscriptions$1 = [];
|
|
|
26000
26288
|
async function runMqtt() {
|
|
26001
26289
|
await modifyMqttConnection();
|
|
26002
26290
|
}
|
|
26003
|
-
const isSameUserId = (token) => {
|
|
26004
|
-
var _a;
|
|
26005
|
-
const client = getActiveClient();
|
|
26006
|
-
const decoded = jwtDecode(token);
|
|
26007
|
-
return ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) === client.userId;
|
|
26008
|
-
};
|
|
26009
|
-
const validateAccessToken = async ({ token, userId }) => {
|
|
26010
|
-
const client = getActiveClient();
|
|
26011
|
-
// begin establishing session
|
|
26012
|
-
setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
|
|
26013
|
-
const { data: { users }, } = await client.http.get(`/api/v3/users/${userId}`, {
|
|
26014
|
-
headers: {
|
|
26015
|
-
Authorization: `Bearer ${token.accessToken}`,
|
|
26016
|
-
},
|
|
26017
|
-
});
|
|
26018
|
-
const user = users.find((u) => u.userId === userId);
|
|
26019
|
-
client.http.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
|
|
26020
|
-
client.http.defaults.metadata = {
|
|
26021
|
-
tokenExpiry: token.expiresAt,
|
|
26022
|
-
isGlobalBanned: false,
|
|
26023
|
-
isUserDeleted: false,
|
|
26024
|
-
};
|
|
26025
|
-
client.upload.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
|
|
26026
|
-
client.upload.defaults.metadata = {
|
|
26027
|
-
tokenExpiry: token.expiresAt,
|
|
26028
|
-
isGlobalBanned: false,
|
|
26029
|
-
isUserDeleted: false,
|
|
26030
|
-
};
|
|
26031
|
-
client.token = token;
|
|
26032
|
-
setSessionState("established" /* Amity.SessionStates.ESTABLISHED */);
|
|
26033
|
-
return user;
|
|
26034
|
-
};
|
|
26035
26291
|
/* begin_public_function
|
|
26036
26292
|
id: client.resumeSession
|
|
26037
26293
|
*/
|
|
@@ -26080,6 +26336,7 @@ const resumeSession = async (params, sessionHandler, config) => {
|
|
|
26080
26336
|
}
|
|
26081
26337
|
}
|
|
26082
26338
|
try {
|
|
26339
|
+
setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
|
|
26083
26340
|
const user = await validateAccessToken(params);
|
|
26084
26341
|
if (user == null) {
|
|
26085
26342
|
throw new ASCError(`${params.userId} has not been found`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
@@ -26186,13 +26443,13 @@ class GlobalFileAccessType {
|
|
|
26186
26443
|
}
|
|
26187
26444
|
}
|
|
26188
26445
|
_GlobalFileAccessType_fileAccessType = new WeakMap();
|
|
26189
|
-
let instance;
|
|
26446
|
+
let instance$1;
|
|
26190
26447
|
var GlobalFileAccessType$1 = {
|
|
26191
26448
|
getInstance: () => {
|
|
26192
|
-
if (!instance) {
|
|
26193
|
-
instance = new GlobalFileAccessType();
|
|
26449
|
+
if (!instance$1) {
|
|
26450
|
+
instance$1 = new GlobalFileAccessType();
|
|
26194
26451
|
}
|
|
26195
|
-
return instance;
|
|
26452
|
+
return instance$1;
|
|
26196
26453
|
},
|
|
26197
26454
|
};
|
|
26198
26455
|
|
|
@@ -26407,11 +26664,12 @@ const loginAsBot = async (params) => {
|
|
|
26407
26664
|
[user] = users;
|
|
26408
26665
|
client.userId = user.userId;
|
|
26409
26666
|
client.sessionHandler = params.sessionHandler;
|
|
26667
|
+
client.loginType = 'userId';
|
|
26410
26668
|
/*
|
|
26411
26669
|
* Cannot push to subscriptions as watcher needs to continue working even if
|
|
26412
26670
|
* token expires
|
|
26413
26671
|
*/
|
|
26414
|
-
unsubWatcher = client.accessTokenExpiryWatcher(
|
|
26672
|
+
unsubWatcher = client.accessTokenExpiryWatcher();
|
|
26415
26673
|
setCurrentUser({ user, userType });
|
|
26416
26674
|
}
|
|
26417
26675
|
catch (error) {
|
|
@@ -26440,6 +26698,53 @@ const loginAsBot = async (params) => {
|
|
|
26440
26698
|
};
|
|
26441
26699
|
/* end_public_function */
|
|
26442
26700
|
|
|
26701
|
+
/* begin_public_function
|
|
26702
|
+
id: client.setAccessTokenHandler
|
|
26703
|
+
*/
|
|
26704
|
+
/**
|
|
26705
|
+
* ```js
|
|
26706
|
+
* import { setAccessTokenHandler } from '@amityco/ts-sdk'
|
|
26707
|
+
*
|
|
26708
|
+
* const tokenHandler = {
|
|
26709
|
+
* async onTokenRenew() {
|
|
26710
|
+
* const response = await fetch('https://your-backend.com/api/refresh-token', {
|
|
26711
|
+
* method: 'POST',
|
|
26712
|
+
* credentials: 'include',
|
|
26713
|
+
* });
|
|
26714
|
+
* const data = await response.json();
|
|
26715
|
+
* return data.accessToken;
|
|
26716
|
+
* }
|
|
26717
|
+
* };
|
|
26718
|
+
*
|
|
26719
|
+
* setAccessTokenHandler(tokenHandler);
|
|
26720
|
+
* ```
|
|
26721
|
+
*
|
|
26722
|
+
* Registers a custom handler for managing access token renewal and expiration events.
|
|
26723
|
+
* This enables automatic token refresh and graceful handling of expired tokens.
|
|
26724
|
+
*
|
|
26725
|
+
* Must be called before loginWithAccessToken() to ensure the handler is available
|
|
26726
|
+
* when token expiry is detected.
|
|
26727
|
+
*
|
|
26728
|
+
* @param accessTokenHandler Handler object implementing token renewal callbacks
|
|
26729
|
+
* @returns void
|
|
26730
|
+
*
|
|
26731
|
+
* @category Client API
|
|
26732
|
+
*/
|
|
26733
|
+
const setAccessTokenHandler = (accessTokenHandler) => {
|
|
26734
|
+
const client = getActiveClient();
|
|
26735
|
+
client.log('client/api/setAccessTokenHandler', {
|
|
26736
|
+
apiKey: client.apiKey,
|
|
26737
|
+
sessionState: client.sessionState,
|
|
26738
|
+
hasOnTokenRenew: typeof (accessTokenHandler === null || accessTokenHandler === void 0 ? void 0 : accessTokenHandler.onTokenRenew) === 'function',
|
|
26739
|
+
});
|
|
26740
|
+
// Validate handler has required method
|
|
26741
|
+
if (!accessTokenHandler || typeof accessTokenHandler.onTokenRenew !== 'function') {
|
|
26742
|
+
throw new Error('AccessTokenHandler must implement onTokenRenew() method');
|
|
26743
|
+
}
|
|
26744
|
+
// Register the handler
|
|
26745
|
+
client.accessTokenHandler = accessTokenHandler;
|
|
26746
|
+
};
|
|
26747
|
+
|
|
26443
26748
|
/**
|
|
26444
26749
|
* ```js
|
|
26445
26750
|
* import { onChannelMarkerFetched } from '@amityco/ts-sdk-react-native'
|
|
@@ -26799,6 +27104,7 @@ var index$r = /*#__PURE__*/Object.freeze({
|
|
|
26799
27104
|
setActiveUser: setActiveUser,
|
|
26800
27105
|
createClient: createClient,
|
|
26801
27106
|
login: login,
|
|
27107
|
+
loginWithAccessToken: loginWithAccessToken,
|
|
26802
27108
|
logout: logout,
|
|
26803
27109
|
secureLogout: secureLogout,
|
|
26804
27110
|
resumeSession: resumeSession,
|
|
@@ -26820,6 +27126,7 @@ var index$r = /*#__PURE__*/Object.freeze({
|
|
|
26820
27126
|
getCurrentUser: getCurrentUser,
|
|
26821
27127
|
getCurrentUserType: getCurrentUserType,
|
|
26822
27128
|
setCurrentUserType: setCurrentUserType,
|
|
27129
|
+
setAccessTokenHandler: setAccessTokenHandler,
|
|
26823
27130
|
onConnectionError: onConnectionError,
|
|
26824
27131
|
onClientDisconnected: onClientDisconnected,
|
|
26825
27132
|
onClientBanned: onClientBanned,
|
|
@@ -33177,6 +33484,147 @@ removeReaction.optimistically = (referenceType, referenceId, reactionName) => {
|
|
|
33177
33484
|
return !((_d = reaction === null || reaction === void 0 ? void 0 : reaction.myReactions) === null || _d === void 0 ? void 0 : _d.includes(reactionName));
|
|
33178
33485
|
};
|
|
33179
33486
|
|
|
33487
|
+
class ResetTask {
|
|
33488
|
+
constructor(postId, latestCreatedAt, serverCommentCount) {
|
|
33489
|
+
this.postId = postId;
|
|
33490
|
+
this.latestCreatedAt = latestCreatedAt;
|
|
33491
|
+
this.serverCommentCount = serverCommentCount;
|
|
33492
|
+
}
|
|
33493
|
+
}
|
|
33494
|
+
|
|
33495
|
+
// Task to track comment creation
|
|
33496
|
+
class CreateTask {
|
|
33497
|
+
constructor(postId, commentId, createdAt) {
|
|
33498
|
+
this.postId = postId;
|
|
33499
|
+
this.commentId = commentId;
|
|
33500
|
+
this.createdAt = createdAt;
|
|
33501
|
+
}
|
|
33502
|
+
}
|
|
33503
|
+
|
|
33504
|
+
// Task to track comment deletion
|
|
33505
|
+
class DeleteTask {
|
|
33506
|
+
constructor(postId, commentId) {
|
|
33507
|
+
this.postId = postId;
|
|
33508
|
+
this.commentId = commentId;
|
|
33509
|
+
}
|
|
33510
|
+
}
|
|
33511
|
+
|
|
33512
|
+
class CommentChange {
|
|
33513
|
+
constructor(latestCreatedAt, serverCommentCount) {
|
|
33514
|
+
this.latestCommentCreatedAt = latestCreatedAt;
|
|
33515
|
+
this.serverCommentCount = serverCommentCount;
|
|
33516
|
+
this.createdCommentIds = new Set();
|
|
33517
|
+
this.deletedCommentIds = new Set();
|
|
33518
|
+
}
|
|
33519
|
+
}
|
|
33520
|
+
|
|
33521
|
+
class PostCommentCountEngine {
|
|
33522
|
+
constructor() {
|
|
33523
|
+
this.isProcessing = false;
|
|
33524
|
+
this.tasks = [];
|
|
33525
|
+
this.commentChangeTracker = new Map();
|
|
33526
|
+
}
|
|
33527
|
+
queueCommentChangeTask(task) {
|
|
33528
|
+
this.tasks.push(task);
|
|
33529
|
+
if (!this.isProcessing) {
|
|
33530
|
+
this.processCommentChangeTask();
|
|
33531
|
+
}
|
|
33532
|
+
}
|
|
33533
|
+
processCommentChangeTask() {
|
|
33534
|
+
if (this.isProcessing) {
|
|
33535
|
+
return;
|
|
33536
|
+
}
|
|
33537
|
+
this.isProcessing = true;
|
|
33538
|
+
if (this.tasks.length === 0) {
|
|
33539
|
+
this.isProcessing = false;
|
|
33540
|
+
return;
|
|
33541
|
+
}
|
|
33542
|
+
// Process in capped batches, coalescing updates
|
|
33543
|
+
const batch = this.tasks.splice(0, PostCommentCountEngine.BATCH_SIZE);
|
|
33544
|
+
const modifiedPostIds = new Set();
|
|
33545
|
+
batch.forEach(task => {
|
|
33546
|
+
let modified = false;
|
|
33547
|
+
if (task instanceof ResetTask) {
|
|
33548
|
+
modified = this.processResetTaskInternal(task);
|
|
33549
|
+
}
|
|
33550
|
+
else if (task instanceof CreateTask) {
|
|
33551
|
+
modified = this.processCreateTaskInternal(task);
|
|
33552
|
+
}
|
|
33553
|
+
else if (task instanceof DeleteTask) {
|
|
33554
|
+
modified = this.processDeleteTaskInternal(task);
|
|
33555
|
+
}
|
|
33556
|
+
if (modified) {
|
|
33557
|
+
modifiedPostIds.add(task.postId);
|
|
33558
|
+
}
|
|
33559
|
+
});
|
|
33560
|
+
// Publish one update per modified post
|
|
33561
|
+
modifiedPostIds.forEach(postId => {
|
|
33562
|
+
const count = this.computeCommentCount(postId);
|
|
33563
|
+
PostCommentCountEngine.publishUpdate(postId, count);
|
|
33564
|
+
});
|
|
33565
|
+
this.isProcessing = false;
|
|
33566
|
+
// Recurse if more tasks remain
|
|
33567
|
+
if (this.tasks.length > 0) {
|
|
33568
|
+
this.processCommentChangeTask();
|
|
33569
|
+
}
|
|
33570
|
+
}
|
|
33571
|
+
processResetTaskInternal(task) {
|
|
33572
|
+
// Always creates/overwrites tracker
|
|
33573
|
+
this.commentChangeTracker.set(task.postId, new CommentChange(task.latestCreatedAt, task.serverCommentCount));
|
|
33574
|
+
return true;
|
|
33575
|
+
}
|
|
33576
|
+
processCreateTaskInternal(task) {
|
|
33577
|
+
const tracker = this.commentChangeTracker.get(task.postId);
|
|
33578
|
+
if (!tracker)
|
|
33579
|
+
return false; // No tracker, skip
|
|
33580
|
+
if (tracker.createdCommentIds.has(task.commentId))
|
|
33581
|
+
return false; // Deduplication
|
|
33582
|
+
if (task.createdAt <= tracker.latestCommentCreatedAt)
|
|
33583
|
+
return false; // Timestamp filtering
|
|
33584
|
+
tracker.createdCommentIds.add(task.commentId);
|
|
33585
|
+
return true;
|
|
33586
|
+
}
|
|
33587
|
+
processDeleteTaskInternal(task) {
|
|
33588
|
+
const tracker = this.commentChangeTracker.get(task.postId);
|
|
33589
|
+
if (!tracker)
|
|
33590
|
+
return false; // No tracker, skip
|
|
33591
|
+
if (tracker.deletedCommentIds.has(task.commentId))
|
|
33592
|
+
return false; // Deduplication
|
|
33593
|
+
tracker.deletedCommentIds.add(task.commentId);
|
|
33594
|
+
return true;
|
|
33595
|
+
}
|
|
33596
|
+
computeCommentCount(postId) {
|
|
33597
|
+
const tracker = this.commentChangeTracker.get(postId);
|
|
33598
|
+
if (!tracker)
|
|
33599
|
+
return 0;
|
|
33600
|
+
const count = tracker.serverCommentCount + tracker.createdCommentIds.size - tracker.deletedCommentIds.size;
|
|
33601
|
+
return Math.max(0, count);
|
|
33602
|
+
}
|
|
33603
|
+
static publishUpdate(postId, newCount) {
|
|
33604
|
+
var _a;
|
|
33605
|
+
const queryKey = ['post', 'get', postId];
|
|
33606
|
+
mergeInCache(queryKey, {
|
|
33607
|
+
localCommentCount: newCount,
|
|
33608
|
+
});
|
|
33609
|
+
const postPayload = (_a = pullFromCache(queryKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
33610
|
+
if (!postPayload)
|
|
33611
|
+
return;
|
|
33612
|
+
fireEvent('local.post.updated', {
|
|
33613
|
+
posts: [postPayload],
|
|
33614
|
+
});
|
|
33615
|
+
}
|
|
33616
|
+
}
|
|
33617
|
+
PostCommentCountEngine.BATCH_SIZE = 50;
|
|
33618
|
+
let instance;
|
|
33619
|
+
var PostCommentCountEngine$1 = {
|
|
33620
|
+
getInstance: () => {
|
|
33621
|
+
if (!instance) {
|
|
33622
|
+
instance = new PostCommentCountEngine();
|
|
33623
|
+
}
|
|
33624
|
+
return instance;
|
|
33625
|
+
},
|
|
33626
|
+
};
|
|
33627
|
+
|
|
33180
33628
|
const updateStreamReferences = (streams, streamId, postId) => {
|
|
33181
33629
|
if (!streamId)
|
|
33182
33630
|
return streams;
|
|
@@ -33196,14 +33644,26 @@ const preparePostPayload = (payload) => {
|
|
|
33196
33644
|
let mappedNewStream = [];
|
|
33197
33645
|
// feed type
|
|
33198
33646
|
const posts = postsData.map(post => {
|
|
33199
|
-
var _a, _b;
|
|
33647
|
+
var _a, _b, _c, _d;
|
|
33200
33648
|
const feedType = (_a = postPayload.feeds.find(feed => feed.feedId === post.feedId)) === null || _a === void 0 ? void 0 : _a.feedType;
|
|
33201
33649
|
const childPosts = payload.postChildren.filter(children => children.parentPostId === post.postId);
|
|
33202
33650
|
if (childPosts.length > 0 && isAmityLivestreamPost(childPosts[0])) {
|
|
33203
33651
|
mappedNewStream = updateStreamReferences(videoStreamings, (_b = childPosts[0].data) === null || _b === void 0 ? void 0 : _b.streamId, post.postId);
|
|
33204
33652
|
}
|
|
33653
|
+
// --- Computed Comment Count: ResetTask integration ---
|
|
33654
|
+
// Find all comments for this post (referenceType === 'post' && referenceId === postId)
|
|
33655
|
+
const allComments = (payload.comments || []).filter((c) => c.referenceType === 'post' && c.referenceId === post.postId);
|
|
33656
|
+
// Compute latestCreatedAt
|
|
33657
|
+
const latestCreatedAt = allComments.length === 0
|
|
33658
|
+
? new Date().toISOString()
|
|
33659
|
+
: allComments
|
|
33660
|
+
.map(c => c.createdAt)
|
|
33661
|
+
.sort()
|
|
33662
|
+
.at(-1);
|
|
33663
|
+
// Queue ResetTask for this post
|
|
33664
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new ResetTask(post.postId, latestCreatedAt, (_c = post.commentsCount) !== null && _c !== void 0 ? _c : 0));
|
|
33205
33665
|
return Object.assign(Object.assign({}, post), { childPosts,
|
|
33206
|
-
feedType });
|
|
33666
|
+
feedType, localCommentCount: (_d = post.localCommentCount) !== null && _d !== void 0 ? _d : post.commentsCount });
|
|
33207
33667
|
});
|
|
33208
33668
|
return Object.assign(Object.assign({}, postPayload), { postChildren, videoStreamings: mappedNewStream, posts, communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
33209
33669
|
};
|
|
@@ -33305,14 +33765,12 @@ const createLocalPostEventSubscriber = (event, callback) => {
|
|
|
33305
33765
|
callback(payload.posts[0]);
|
|
33306
33766
|
}
|
|
33307
33767
|
else {
|
|
33308
|
-
const
|
|
33309
|
-
const { communities } = data;
|
|
33310
|
-
ingestInCache(data);
|
|
33768
|
+
const { communities } = payload;
|
|
33311
33769
|
if ((communities === null || communities === void 0 ? void 0 : communities[0]) && !['local.post.updated'].includes(event)) {
|
|
33312
33770
|
fireEvent('community.updated', {
|
|
33313
33771
|
communities,
|
|
33314
33772
|
categories: [],
|
|
33315
|
-
communityUsers:
|
|
33773
|
+
communityUsers: payload.communityUsers,
|
|
33316
33774
|
feeds: [],
|
|
33317
33775
|
files: [],
|
|
33318
33776
|
users: [],
|
|
@@ -33583,7 +34041,7 @@ const createCommentEventSubscriber = (event, callback) => {
|
|
|
33583
34041
|
const createLocalCommentEventSubscriber = (event, callback) => {
|
|
33584
34042
|
const client = getActiveClient();
|
|
33585
34043
|
const filter = (payload) => {
|
|
33586
|
-
var _a, _b;
|
|
34044
|
+
var _a, _b, _c, _d, _e;
|
|
33587
34045
|
if (!client.cache) {
|
|
33588
34046
|
// TODO: here we are missing specific properties here!
|
|
33589
34047
|
callback(LinkedObject.comment(payload.comments[0]));
|
|
@@ -33623,7 +34081,13 @@ const createLocalCommentEventSubscriber = (event, callback) => {
|
|
|
33623
34081
|
}
|
|
33624
34082
|
}
|
|
33625
34083
|
}
|
|
33626
|
-
|
|
34084
|
+
else {
|
|
34085
|
+
const postCacheKey = ['post', 'get', comments[0].referenceId];
|
|
34086
|
+
const postCache = (_a = pullFromCache(postCacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
34087
|
+
postCache === null || postCache === void 0 ? void 0 : postCache.comments.push((_b = comments[0]) === null || _b === void 0 ? void 0 : _b.commentId);
|
|
34088
|
+
pushToCache(postCacheKey, postCache);
|
|
34089
|
+
}
|
|
34090
|
+
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; });
|
|
33627
34091
|
queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
|
|
33628
34092
|
}
|
|
33629
34093
|
if (['local.comment.deleted'].includes(event)) {
|
|
@@ -33655,7 +34119,13 @@ const createLocalCommentEventSubscriber = (event, callback) => {
|
|
|
33655
34119
|
}
|
|
33656
34120
|
}
|
|
33657
34121
|
}
|
|
33658
|
-
|
|
34122
|
+
else {
|
|
34123
|
+
const postCacheKey = ['post', 'get', comments[0].referenceId];
|
|
34124
|
+
const postCache = (_d = pullFromCache(postCacheKey)) === null || _d === void 0 ? void 0 : _d.data;
|
|
34125
|
+
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); }) });
|
|
34126
|
+
pushToCache(postCacheKey, updatedPost);
|
|
34127
|
+
}
|
|
34128
|
+
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; });
|
|
33659
34129
|
queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
|
|
33660
34130
|
}
|
|
33661
34131
|
callback(LinkedObject.comment(comment.data));
|
|
@@ -41365,7 +41835,6 @@ getCommentByIds.locally = (commentIds) => {
|
|
|
41365
41835
|
* @async
|
|
41366
41836
|
*/
|
|
41367
41837
|
const createComment = async (bundle) => {
|
|
41368
|
-
var _a;
|
|
41369
41838
|
const client = getActiveClient();
|
|
41370
41839
|
client.log('comment/createComment', bundle);
|
|
41371
41840
|
const { data } = await client.http.post('/api/v3/comments', bundle);
|
|
@@ -41377,22 +41846,7 @@ const createComment = async (bundle) => {
|
|
|
41377
41846
|
if (client.cache)
|
|
41378
41847
|
ingestInCache(data, { cachedAt });
|
|
41379
41848
|
if (['post', 'content'].includes(bundle.referenceType)) {
|
|
41380
|
-
|
|
41381
|
-
if (post) {
|
|
41382
|
-
post.commentsCount += 1;
|
|
41383
|
-
fireEvent('local.post.updated', {
|
|
41384
|
-
posts: [post],
|
|
41385
|
-
categories: [],
|
|
41386
|
-
comments: [],
|
|
41387
|
-
communities: [],
|
|
41388
|
-
communityUsers: data.communityUsers,
|
|
41389
|
-
feeds: [],
|
|
41390
|
-
files: data.files,
|
|
41391
|
-
postChildren: [],
|
|
41392
|
-
users: data.users,
|
|
41393
|
-
videoStreamings: [],
|
|
41394
|
-
});
|
|
41395
|
-
}
|
|
41849
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new CreateTask(bundle.referenceId, comments[0].commentId, data.comments[0].createdAt));
|
|
41396
41850
|
}
|
|
41397
41851
|
else if (bundle.referenceType === 'story') {
|
|
41398
41852
|
const storyIndex = pullFromCache([
|
|
@@ -41551,7 +42005,7 @@ getStoryByStoryId$1.locally = (storyId) => {
|
|
|
41551
42005
|
* @async
|
|
41552
42006
|
*/
|
|
41553
42007
|
const deleteComment = async (commentId, permanent = false) => {
|
|
41554
|
-
var _a;
|
|
42008
|
+
var _a, _b;
|
|
41555
42009
|
const client = getActiveClient();
|
|
41556
42010
|
const comment = await getComment$2(commentId);
|
|
41557
42011
|
// API-FIX: This endpoint has not been implemented yet.
|
|
@@ -41584,26 +42038,14 @@ const deleteComment = async (commentId, permanent = false) => {
|
|
|
41584
42038
|
else {
|
|
41585
42039
|
const post = (_a = pullFromCache(['post', 'get', comment.data.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
41586
42040
|
if (post) {
|
|
41587
|
-
|
|
41588
|
-
|
|
41589
|
-
|
|
41590
|
-
|
|
42041
|
+
const engine = PostCommentCountEngine$1.getInstance();
|
|
42042
|
+
engine.queueCommentChangeTask(new DeleteTask(post.postId, commentId));
|
|
42043
|
+
if (!deleted.parentId && ((_b = deleted.children) === null || _b === void 0 ? void 0 : _b.length) > 0) {
|
|
42044
|
+
// NOTE: delete the parent comment will also remove all children comments
|
|
42045
|
+
deleted.children.forEach((childCommentId) => {
|
|
42046
|
+
engine.queueCommentChangeTask(new DeleteTask(post.postId, childCommentId));
|
|
42047
|
+
});
|
|
41591
42048
|
}
|
|
41592
|
-
else
|
|
41593
|
-
removeCount = 1;
|
|
41594
|
-
post.commentsCount -= removeCount;
|
|
41595
|
-
fireEvent('local.post.updated', {
|
|
41596
|
-
posts: [post],
|
|
41597
|
-
categories: [],
|
|
41598
|
-
comments: [],
|
|
41599
|
-
communities: [],
|
|
41600
|
-
communityUsers: [],
|
|
41601
|
-
feeds: [],
|
|
41602
|
-
files: [],
|
|
41603
|
-
postChildren: [],
|
|
41604
|
-
users: [],
|
|
41605
|
-
videoStreamings: [],
|
|
41606
|
-
});
|
|
41607
42049
|
}
|
|
41608
42050
|
}
|
|
41609
42051
|
fireEvent('local.comment.deleted', {
|
|
@@ -42169,47 +42611,6 @@ var index$d = /*#__PURE__*/Object.freeze({
|
|
|
42169
42611
|
getComments: getComments
|
|
42170
42612
|
});
|
|
42171
42613
|
|
|
42172
|
-
const getPost$1 = async (postId) => {
|
|
42173
|
-
const client = getActiveClient();
|
|
42174
|
-
client.log('post/getPost', postId);
|
|
42175
|
-
isInTombstone('post', postId);
|
|
42176
|
-
let payload;
|
|
42177
|
-
try {
|
|
42178
|
-
// API-FIX: endpoint should not be /list, parameters should be querystring.
|
|
42179
|
-
const response = await client.http.get(`/api/v3/posts/${encodeURIComponent(postId)}`);
|
|
42180
|
-
payload = response.data;
|
|
42181
|
-
}
|
|
42182
|
-
catch (error) {
|
|
42183
|
-
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
42184
|
-
pushToTombstone('post', postId);
|
|
42185
|
-
}
|
|
42186
|
-
throw error;
|
|
42187
|
-
}
|
|
42188
|
-
const data = prepareMembershipPayload(payload, 'communityUsers');
|
|
42189
|
-
const cachedAt = client.cache && Date.now();
|
|
42190
|
-
if (client.cache)
|
|
42191
|
-
ingestInCache(data, { cachedAt });
|
|
42192
|
-
const { posts } = data;
|
|
42193
|
-
const result = posts.find(post => post.postId === postId);
|
|
42194
|
-
return {
|
|
42195
|
-
data: result,
|
|
42196
|
-
cachedAt,
|
|
42197
|
-
};
|
|
42198
|
-
};
|
|
42199
|
-
getPost$1.locally = (postId) => {
|
|
42200
|
-
const client = getActiveClient();
|
|
42201
|
-
client.log('post/getPost.locally', postId);
|
|
42202
|
-
if (!client.cache)
|
|
42203
|
-
return;
|
|
42204
|
-
const cached = pullFromCache(['post', 'get', postId]);
|
|
42205
|
-
if (!cached)
|
|
42206
|
-
return;
|
|
42207
|
-
return {
|
|
42208
|
-
data: cached.data,
|
|
42209
|
-
cachedAt: cached.cachedAt,
|
|
42210
|
-
};
|
|
42211
|
-
};
|
|
42212
|
-
|
|
42213
42614
|
/**
|
|
42214
42615
|
* ```js
|
|
42215
42616
|
* import { onLocalPostDeleted } from '@amityco/ts-sdk-react-native'
|
|
@@ -42308,7 +42709,6 @@ const commentEventHandler$1 = (callback, eventHandler, cacheKey) => {
|
|
|
42308
42709
|
const currentCollection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
42309
42710
|
if (!currentCollection || !currentCollection.data.includes(comment.referenceId))
|
|
42310
42711
|
return;
|
|
42311
|
-
await getPost$1(comment.referenceId);
|
|
42312
42712
|
callback(comment);
|
|
42313
42713
|
});
|
|
42314
42714
|
};
|
|
@@ -42316,12 +42716,8 @@ const generateCommentSubscriptions$1 = (cacheKey) => {
|
|
|
42316
42716
|
const eventHandlers = [
|
|
42317
42717
|
onCommentCreated,
|
|
42318
42718
|
onCommentDeleted,
|
|
42319
|
-
onCommentReactionAdded,
|
|
42320
|
-
onCommentReactionRemoved,
|
|
42321
42719
|
onCommentCreatedLocal,
|
|
42322
42720
|
onCommentDeleteLocal,
|
|
42323
|
-
onLocalCommentReactionAdded,
|
|
42324
|
-
onLocalCommentReactionRemoved,
|
|
42325
42721
|
];
|
|
42326
42722
|
return eventHandlers.map(handler => ({
|
|
42327
42723
|
fn: convertEventPayload((callback) => commentEventHandler$1(callback, handler, cacheKey), 'referenceId', 'post'),
|
|
@@ -42685,6 +43081,47 @@ class UserFeedQueryStreamController extends QueryStreamController {
|
|
|
42685
43081
|
}
|
|
42686
43082
|
}
|
|
42687
43083
|
|
|
43084
|
+
const getPost$1 = async (postId) => {
|
|
43085
|
+
const client = getActiveClient();
|
|
43086
|
+
client.log('post/getPost', postId);
|
|
43087
|
+
isInTombstone('post', postId);
|
|
43088
|
+
let payload;
|
|
43089
|
+
try {
|
|
43090
|
+
// API-FIX: endpoint should not be /list, parameters should be querystring.
|
|
43091
|
+
const response = await client.http.get(`/api/v3/posts/${encodeURIComponent(postId)}`);
|
|
43092
|
+
payload = response.data;
|
|
43093
|
+
}
|
|
43094
|
+
catch (error) {
|
|
43095
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
43096
|
+
pushToTombstone('post', postId);
|
|
43097
|
+
}
|
|
43098
|
+
throw error;
|
|
43099
|
+
}
|
|
43100
|
+
const data = prepareMembershipPayload(payload, 'communityUsers');
|
|
43101
|
+
const cachedAt = client.cache && Date.now();
|
|
43102
|
+
if (client.cache)
|
|
43103
|
+
ingestInCache(data, { cachedAt });
|
|
43104
|
+
const { posts } = data;
|
|
43105
|
+
const result = posts.find(post => post.postId === postId);
|
|
43106
|
+
return {
|
|
43107
|
+
data: result,
|
|
43108
|
+
cachedAt,
|
|
43109
|
+
};
|
|
43110
|
+
};
|
|
43111
|
+
getPost$1.locally = (postId) => {
|
|
43112
|
+
const client = getActiveClient();
|
|
43113
|
+
client.log('post/getPost.locally', postId);
|
|
43114
|
+
if (!client.cache)
|
|
43115
|
+
return;
|
|
43116
|
+
const cached = pullFromCache(['post', 'get', postId]);
|
|
43117
|
+
if (!cached)
|
|
43118
|
+
return;
|
|
43119
|
+
return {
|
|
43120
|
+
data: cached.data,
|
|
43121
|
+
cachedAt: cached.cachedAt,
|
|
43122
|
+
};
|
|
43123
|
+
};
|
|
43124
|
+
|
|
42688
43125
|
class UserFeedLiveCollectionController extends LiveCollectionController {
|
|
42689
43126
|
constructor(query, callback) {
|
|
42690
43127
|
const queryStreamId = hash(query);
|
|
@@ -42818,12 +43255,240 @@ const getUserFeed = (params, callback, config) => {
|
|
|
42818
43255
|
};
|
|
42819
43256
|
/* end_public_function */
|
|
42820
43257
|
|
|
43258
|
+
class CommunityFeedPaginationController extends PaginationController {
|
|
43259
|
+
async getRequest(queryParams, token) {
|
|
43260
|
+
const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, includeDeleted, communityId } = queryParams, params = __rest(queryParams, ["limit", "includeDeleted", "communityId"]);
|
|
43261
|
+
const options = token ? { token } : { limit };
|
|
43262
|
+
const { data: queryResponse } = await this.http.get(`/api/v5/posts`, {
|
|
43263
|
+
params: Object.assign(Object.assign({}, params), { targetId: communityId, targetType: 'community', isDeleted: inferIsDeleted(includeDeleted), matchingOnlyParentPost: true, options }),
|
|
43264
|
+
});
|
|
43265
|
+
return queryResponse;
|
|
43266
|
+
}
|
|
43267
|
+
}
|
|
43268
|
+
|
|
43269
|
+
class CommunityFeedQueryStreamController extends QueryStreamController {
|
|
43270
|
+
constructor(query, cacheKey, notifyChange, preparePayload) {
|
|
43271
|
+
super(query, cacheKey);
|
|
43272
|
+
this.notifyChange = notifyChange;
|
|
43273
|
+
this.preparePayload = preparePayload;
|
|
43274
|
+
}
|
|
43275
|
+
async saveToMainDB(response) {
|
|
43276
|
+
const processedPayload = await this.preparePayload(response);
|
|
43277
|
+
const client = getActiveClient();
|
|
43278
|
+
const cachedAt = client.cache && Date.now();
|
|
43279
|
+
if (client.cache) {
|
|
43280
|
+
ingestInCache(processedPayload, { cachedAt });
|
|
43281
|
+
}
|
|
43282
|
+
}
|
|
43283
|
+
appendToQueryStream(response, direction, refresh = false) {
|
|
43284
|
+
var _a, _b;
|
|
43285
|
+
if (refresh) {
|
|
43286
|
+
pushToCache(this.cacheKey, {
|
|
43287
|
+
data: response.posts.map(getResolver('post')),
|
|
43288
|
+
});
|
|
43289
|
+
}
|
|
43290
|
+
else {
|
|
43291
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
43292
|
+
const posts = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
43293
|
+
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...posts, ...response.posts.map(getResolver('post'))])] }));
|
|
43294
|
+
}
|
|
43295
|
+
}
|
|
43296
|
+
reactor(action) {
|
|
43297
|
+
return (post) => {
|
|
43298
|
+
var _a, _b;
|
|
43299
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
43300
|
+
if (!collection)
|
|
43301
|
+
return;
|
|
43302
|
+
if (action === EnumPostActions.OnPostDeleted) {
|
|
43303
|
+
collection.data = collection.data.filter(postId => postId !== post.postId);
|
|
43304
|
+
}
|
|
43305
|
+
if (post.parentPostId && post.isDeleted) {
|
|
43306
|
+
const parentPost = (_b = pullFromCache([
|
|
43307
|
+
'post',
|
|
43308
|
+
'get',
|
|
43309
|
+
post.parentPostId,
|
|
43310
|
+
])) === null || _b === void 0 ? void 0 : _b.data;
|
|
43311
|
+
if (!parentPost)
|
|
43312
|
+
return;
|
|
43313
|
+
parentPost.children = parentPost.children.filter(childId => childId !== post.postId);
|
|
43314
|
+
pushToCache(['post', 'get', parentPost.postId], parentPost);
|
|
43315
|
+
}
|
|
43316
|
+
if (action === EnumPostActions.OnPostDeclined) {
|
|
43317
|
+
collection.data = collection.data.filter(postId => postId !== post.postId);
|
|
43318
|
+
}
|
|
43319
|
+
if (action === EnumPostActions.OnPostCreated || action === EnumPostActions.OnPostApproved) {
|
|
43320
|
+
collection.data = [...new Set([post.postId, ...collection.data])];
|
|
43321
|
+
}
|
|
43322
|
+
pushToCache(this.cacheKey, collection);
|
|
43323
|
+
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
43324
|
+
};
|
|
43325
|
+
}
|
|
43326
|
+
subscribeRTE(createSubscriber) {
|
|
43327
|
+
return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
|
|
43328
|
+
}
|
|
43329
|
+
}
|
|
43330
|
+
|
|
43331
|
+
const commentEventHandler = (callback, eventHandler, cacheKey, resolveId) => {
|
|
43332
|
+
return eventHandler(async (comment) => {
|
|
43333
|
+
var _a;
|
|
43334
|
+
const currentCollection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
43335
|
+
if (!currentCollection ||
|
|
43336
|
+
!currentCollection.data.includes(resolveId ? resolveId(comment.referenceId) : comment.referenceId))
|
|
43337
|
+
return;
|
|
43338
|
+
callback(comment);
|
|
43339
|
+
});
|
|
43340
|
+
};
|
|
43341
|
+
const generateCommentSubscriptions = ({ cacheKey, resolveId, }) => {
|
|
43342
|
+
const eventHandlers = [
|
|
43343
|
+
onCommentCreated,
|
|
43344
|
+
onCommentDeleted,
|
|
43345
|
+
onCommentCreatedLocal,
|
|
43346
|
+
onCommentDeleteLocal,
|
|
43347
|
+
];
|
|
43348
|
+
return eventHandlers.map(handler => ({
|
|
43349
|
+
fn: convertEventPayload((callback) => commentEventHandler(callback, handler, cacheKey, resolveId), 'referenceId', 'post'),
|
|
43350
|
+
action: EnumPostActions.OnPostUpdated,
|
|
43351
|
+
}));
|
|
43352
|
+
};
|
|
43353
|
+
const getPostSubscription = (cacheKey) => {
|
|
43354
|
+
return [
|
|
43355
|
+
{ fn: onPostCreated, action: EnumPostActions.OnPostCreated },
|
|
43356
|
+
{ fn: onPostUpdated, action: EnumPostActions.OnPostUpdated },
|
|
43357
|
+
{ fn: onPostUpdatedLocal, action: EnumPostActions.OnPostUpdated },
|
|
43358
|
+
{ fn: onPostDeleted, action: EnumPostActions.OnPostDeleted },
|
|
43359
|
+
{ fn: onPostFlagged, action: EnumPostActions.OnPostFlagged },
|
|
43360
|
+
{ fn: onPostUnflagged, action: EnumPostActions.OnPostUnflagged },
|
|
43361
|
+
{ fn: onPostApproved, action: EnumPostActions.OnPostApproved },
|
|
43362
|
+
{ fn: onPostDeclined, action: EnumPostActions.OnPostDeclined },
|
|
43363
|
+
{ fn: onPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
|
|
43364
|
+
{ fn: onPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
|
|
43365
|
+
{ fn: onLocalPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
|
|
43366
|
+
{ fn: onLocalPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
|
|
43367
|
+
{ fn: onLocalPostDeleted, action: EnumPostActions.OnPostDeleted },
|
|
43368
|
+
...generateCommentSubscriptions({ cacheKey }),
|
|
43369
|
+
];
|
|
43370
|
+
};
|
|
43371
|
+
const resolvePostIdsFromRooms = (rooms, posts) => {
|
|
43372
|
+
var _a;
|
|
43373
|
+
return ((_a = rooms
|
|
43374
|
+
.map(room => {
|
|
43375
|
+
const post = posts.find(post => post.postId === room.referenceId);
|
|
43376
|
+
return post ? getResolver('post')({ postId: post === null || post === void 0 ? void 0 : post.postId }) : undefined;
|
|
43377
|
+
})
|
|
43378
|
+
.filter(isNonNullable)) !== null && _a !== void 0 ? _a : []);
|
|
43379
|
+
};
|
|
43380
|
+
|
|
43381
|
+
class CommunityFeedLiveCollectionController extends LiveCollectionController {
|
|
43382
|
+
constructor(query, callback) {
|
|
43383
|
+
const queryStreamId = hash(query);
|
|
43384
|
+
const cacheKey = ['communityFeed', 'collection', queryStreamId];
|
|
43385
|
+
const paginationController = new CommunityFeedPaginationController(query);
|
|
43386
|
+
super(paginationController, queryStreamId, cacheKey, callback);
|
|
43387
|
+
this.query = query;
|
|
43388
|
+
this.queryStreamController = new CommunityFeedQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), preparePostPayload);
|
|
43389
|
+
this.callback = callback.bind(this);
|
|
43390
|
+
this.loadPage({ initial: true });
|
|
43391
|
+
}
|
|
43392
|
+
setup() {
|
|
43393
|
+
var _a;
|
|
43394
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
43395
|
+
if (!collection) {
|
|
43396
|
+
pushToCache(this.cacheKey, {
|
|
43397
|
+
data: [],
|
|
43398
|
+
params: {},
|
|
43399
|
+
});
|
|
43400
|
+
}
|
|
43401
|
+
}
|
|
43402
|
+
async persistModel(queryPayload) {
|
|
43403
|
+
await this.queryStreamController.saveToMainDB(queryPayload);
|
|
43404
|
+
}
|
|
43405
|
+
persistQueryStream({ response, direction, refresh, }) {
|
|
43406
|
+
this.queryStreamController.appendToQueryStream(response, direction, refresh);
|
|
43407
|
+
}
|
|
43408
|
+
startSubscription() {
|
|
43409
|
+
return this.queryStreamController.subscribeRTE(getPostSubscription(this.cacheKey));
|
|
43410
|
+
}
|
|
43411
|
+
notifyChange({ origin, loading, error }) {
|
|
43412
|
+
var _a, _b;
|
|
43413
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
43414
|
+
if (!collection)
|
|
43415
|
+
return;
|
|
43416
|
+
const data = ((_b = collection.data
|
|
43417
|
+
.map(id => pullFromCache(['post', 'get', id]))
|
|
43418
|
+
.filter(isNonNullable)
|
|
43419
|
+
.map(({ data }) => data)) !== null && _b !== void 0 ? _b : []).map(LinkedObject.post);
|
|
43420
|
+
if (!this.shouldNotify(data) && origin === 'event')
|
|
43421
|
+
return;
|
|
43422
|
+
this.callback({
|
|
43423
|
+
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
43424
|
+
data,
|
|
43425
|
+
hasNextPage: !!this.paginationController.getNextToken(),
|
|
43426
|
+
loading,
|
|
43427
|
+
error,
|
|
43428
|
+
});
|
|
43429
|
+
}
|
|
43430
|
+
}
|
|
43431
|
+
|
|
43432
|
+
/* begin_public_function
|
|
43433
|
+
id: feed.query.community_feed
|
|
43434
|
+
*/
|
|
43435
|
+
/**
|
|
43436
|
+
* ```js
|
|
43437
|
+
* import { FeedRepository } from '@amityco/ts-sdk'
|
|
43438
|
+
*
|
|
43439
|
+
* let posts = []
|
|
43440
|
+
* const unsubscribe = FeedRepository.getCommunityFeed({
|
|
43441
|
+
* communityId: 'community-id',
|
|
43442
|
+
* sortBy?: 'lastCreated' | 'firstCreated' | 'lastUpdated' | 'firstUpdated',
|
|
43443
|
+
* includeDeleted?: boolean,
|
|
43444
|
+
* feedType?: 'reviewing' | 'published' | 'declined',
|
|
43445
|
+
* tags?: string[],
|
|
43446
|
+
* includeMixedStructure?: boolean,
|
|
43447
|
+
* limit?: number,
|
|
43448
|
+
* }, response => processResponse(response))
|
|
43449
|
+
* ```
|
|
43450
|
+
*
|
|
43451
|
+
* Observe all mutations on a list of {@link Amity.Post} for a given community feed.
|
|
43452
|
+
*
|
|
43453
|
+
* @param params - Parameters for querying the community feed:
|
|
43454
|
+
* @param params.communityId The ID of the community (required)
|
|
43455
|
+
* @param params.sortBy The sorting order of the feed (optional)
|
|
43456
|
+
* @param params.includeDeleted Whether to include deleted posts (optional)
|
|
43457
|
+
* @param params.feedType The type of the feed: 'reviewing', 'published', or 'declined' (optional)
|
|
43458
|
+
* @param params.tags Array of tags to filter posts (optional)
|
|
43459
|
+
* @param params.includeMixedStructure Whether to include mixed structure posts (optional)
|
|
43460
|
+
* @param params.limit The maximum number of posts to retrieve (optional)
|
|
43461
|
+
* @param callback The function to call when new data are available
|
|
43462
|
+
* @param config Additional live collection configuration (optional)
|
|
43463
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the feed
|
|
43464
|
+
*
|
|
43465
|
+
* @category Posts Live Collection
|
|
43466
|
+
*/
|
|
43467
|
+
const getCommunityFeed = (params, callback, config) => {
|
|
43468
|
+
const { log, cache } = getActiveClient();
|
|
43469
|
+
if (!cache) {
|
|
43470
|
+
console.log(ENABLE_CACHE_MESSAGE);
|
|
43471
|
+
}
|
|
43472
|
+
const timestamp = Date.now();
|
|
43473
|
+
log(`getCommunityFeed(tmpid: ${timestamp}) > listen`);
|
|
43474
|
+
const communityFeedLiveCollection = new CommunityFeedLiveCollectionController(params, callback);
|
|
43475
|
+
const disposers = communityFeedLiveCollection.startSubscription();
|
|
43476
|
+
const cacheKey = communityFeedLiveCollection.getCacheKey();
|
|
43477
|
+
disposers.push(() => dropFromCache(cacheKey));
|
|
43478
|
+
return () => {
|
|
43479
|
+
log(`getCommunityFeed(tmpid: ${timestamp}) > dispose`);
|
|
43480
|
+
disposers.forEach(fn => fn());
|
|
43481
|
+
};
|
|
43482
|
+
};
|
|
43483
|
+
/* end_public_function */
|
|
43484
|
+
|
|
42821
43485
|
var index$c = /*#__PURE__*/Object.freeze({
|
|
42822
43486
|
__proto__: null,
|
|
42823
43487
|
queryGlobalFeed: queryGlobalFeed,
|
|
42824
43488
|
getCustomRankingGlobalFeed: getCustomRankingGlobalFeed,
|
|
42825
43489
|
getGlobalFeed: getGlobalFeed,
|
|
42826
|
-
getUserFeed: getUserFeed
|
|
43490
|
+
getUserFeed: getUserFeed,
|
|
43491
|
+
getCommunityFeed: getCommunityFeed
|
|
42827
43492
|
});
|
|
42828
43493
|
|
|
42829
43494
|
/* begin_public_function
|
|
@@ -43569,61 +44234,6 @@ class PostQueryStreamController extends QueryStreamController {
|
|
|
43569
44234
|
}
|
|
43570
44235
|
}
|
|
43571
44236
|
|
|
43572
|
-
const commentEventHandler = (callback, eventHandler, cacheKey, resolveId) => {
|
|
43573
|
-
return eventHandler(async (comment) => {
|
|
43574
|
-
var _a;
|
|
43575
|
-
const currentCollection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
43576
|
-
if (!currentCollection ||
|
|
43577
|
-
!currentCollection.data.includes(resolveId ? resolveId(comment.referenceId) : comment.referenceId))
|
|
43578
|
-
return;
|
|
43579
|
-
await getPost$1(comment.referenceId);
|
|
43580
|
-
callback(comment);
|
|
43581
|
-
});
|
|
43582
|
-
};
|
|
43583
|
-
const generateCommentSubscriptions = ({ cacheKey, resolveId, }) => {
|
|
43584
|
-
const eventHandlers = [
|
|
43585
|
-
onCommentCreated,
|
|
43586
|
-
onCommentDeleted,
|
|
43587
|
-
onCommentReactionAdded,
|
|
43588
|
-
onCommentReactionRemoved,
|
|
43589
|
-
onCommentCreatedLocal,
|
|
43590
|
-
onCommentDeleteLocal,
|
|
43591
|
-
onLocalCommentReactionAdded,
|
|
43592
|
-
onLocalCommentReactionRemoved,
|
|
43593
|
-
];
|
|
43594
|
-
return eventHandlers.map(handler => ({
|
|
43595
|
-
fn: convertEventPayload((callback) => commentEventHandler(callback, handler, cacheKey, resolveId), 'referenceId', 'post'),
|
|
43596
|
-
action: EnumPostActions.OnPostUpdated,
|
|
43597
|
-
}));
|
|
43598
|
-
};
|
|
43599
|
-
const getPostSubscription = (cacheKey) => {
|
|
43600
|
-
return [
|
|
43601
|
-
{ fn: onPostCreated, action: EnumPostActions.OnPostCreated },
|
|
43602
|
-
{ fn: onPostUpdated, action: EnumPostActions.OnPostUpdated },
|
|
43603
|
-
{ fn: onPostUpdatedLocal, action: EnumPostActions.OnPostUpdated },
|
|
43604
|
-
{ fn: onPostDeleted, action: EnumPostActions.OnPostDeleted },
|
|
43605
|
-
{ fn: onPostFlagged, action: EnumPostActions.OnPostFlagged },
|
|
43606
|
-
{ fn: onPostUnflagged, action: EnumPostActions.OnPostUnflagged },
|
|
43607
|
-
{ fn: onPostApproved, action: EnumPostActions.OnPostApproved },
|
|
43608
|
-
{ fn: onPostDeclined, action: EnumPostActions.OnPostDeclined },
|
|
43609
|
-
{ fn: onPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
|
|
43610
|
-
{ fn: onPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
|
|
43611
|
-
{ fn: onLocalPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
|
|
43612
|
-
{ fn: onLocalPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
|
|
43613
|
-
{ fn: onLocalPostDeleted, action: EnumPostActions.OnPostDeleted },
|
|
43614
|
-
...generateCommentSubscriptions({ cacheKey }),
|
|
43615
|
-
];
|
|
43616
|
-
};
|
|
43617
|
-
const resolvePostIdsFromRooms = (rooms, posts) => {
|
|
43618
|
-
var _a;
|
|
43619
|
-
return ((_a = rooms
|
|
43620
|
-
.map(room => {
|
|
43621
|
-
const post = posts.find(post => post.postId === room.referenceId);
|
|
43622
|
-
return post ? getResolver('post')({ postId: post === null || post === void 0 ? void 0 : post.postId }) : undefined;
|
|
43623
|
-
})
|
|
43624
|
-
.filter(isNonNullable)) !== null && _a !== void 0 ? _a : []);
|
|
43625
|
-
};
|
|
43626
|
-
|
|
43627
44237
|
class PostLiveCollectionController extends LiveCollectionController {
|
|
43628
44238
|
constructor(query, callback) {
|
|
43629
44239
|
const queryStreamId = hash(query);
|
|
@@ -49979,4 +50589,4 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
49979
50589
|
getRSVPs: getRSVPs
|
|
49980
50590
|
});
|
|
49981
50591
|
|
|
49982
|
-
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 };
|
|
50592
|
+
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 };
|