@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.cjs.js
CHANGED
|
@@ -224,6 +224,12 @@ exports.FeedSourceEnum = void 0;
|
|
|
224
224
|
FeedSourceEnum["Community"] = "community";
|
|
225
225
|
FeedSourceEnum["User"] = "user";
|
|
226
226
|
})(exports.FeedSourceEnum || (exports.FeedSourceEnum = {}));
|
|
227
|
+
exports.FeedTypeEnum = void 0;
|
|
228
|
+
(function (FeedTypeEnum) {
|
|
229
|
+
FeedTypeEnum["Reviewing"] = "reviewing";
|
|
230
|
+
FeedTypeEnum["Published"] = "published";
|
|
231
|
+
FeedTypeEnum["Declined"] = "declined";
|
|
232
|
+
})(exports.FeedTypeEnum || (exports.FeedTypeEnum = {}));
|
|
227
233
|
|
|
228
234
|
exports.AmityEventType = void 0;
|
|
229
235
|
(function (AmityEventType) {
|
|
@@ -260,8 +266,8 @@ exports.AmityEventOrderOption = void 0;
|
|
|
260
266
|
|
|
261
267
|
function getVersion() {
|
|
262
268
|
try {
|
|
263
|
-
// the string ''v7.
|
|
264
|
-
return 'v7.
|
|
269
|
+
// the string ''v7.14.0-cjs'' should be replaced by actual value by @rollup/plugin-replace
|
|
270
|
+
return 'v7.14.0-cjs';
|
|
265
271
|
}
|
|
266
272
|
catch (error) {
|
|
267
273
|
return '__dev__';
|
|
@@ -1715,10 +1721,14 @@ const getLiveReactionTopic = (post) => {
|
|
|
1715
1721
|
};
|
|
1716
1722
|
const getRoomWatcherTopic = (room) => {
|
|
1717
1723
|
const user = getCurrentUser();
|
|
1724
|
+
if (!user)
|
|
1725
|
+
return;
|
|
1718
1726
|
return `${getNetworkId(user)}/room/${room._id}`;
|
|
1719
1727
|
};
|
|
1720
1728
|
const getRoomStreamerTopic = (room) => {
|
|
1721
1729
|
const user = getCurrentUser();
|
|
1730
|
+
if (!user)
|
|
1731
|
+
return;
|
|
1722
1732
|
return `${getNetworkId(user)}/room/${room.roomId}/streamer`;
|
|
1723
1733
|
};
|
|
1724
1734
|
function subscribeTopic(topic, callback) {
|
|
@@ -1813,13 +1823,13 @@ class NetworkActivitiesWatcher {
|
|
|
1813
1823
|
this._listener.clear();
|
|
1814
1824
|
}
|
|
1815
1825
|
}
|
|
1816
|
-
let instance$
|
|
1826
|
+
let instance$8;
|
|
1817
1827
|
var NetworkActivitiesWatcher$1 = {
|
|
1818
1828
|
getInstance: () => {
|
|
1819
|
-
if (!instance$
|
|
1820
|
-
instance$
|
|
1829
|
+
if (!instance$8) {
|
|
1830
|
+
instance$8 = new NetworkActivitiesWatcher();
|
|
1821
1831
|
}
|
|
1822
|
-
return instance$
|
|
1832
|
+
return instance$8;
|
|
1823
1833
|
},
|
|
1824
1834
|
};
|
|
1825
1835
|
|
|
@@ -6914,13 +6924,13 @@ class SessionWatcher {
|
|
|
6914
6924
|
this._listener.clear();
|
|
6915
6925
|
}
|
|
6916
6926
|
}
|
|
6917
|
-
let instance$
|
|
6927
|
+
let instance$7;
|
|
6918
6928
|
var SessionWatcher$1 = {
|
|
6919
6929
|
getInstance: () => {
|
|
6920
|
-
if (!instance$
|
|
6921
|
-
instance$
|
|
6930
|
+
if (!instance$7) {
|
|
6931
|
+
instance$7 = new SessionWatcher();
|
|
6922
6932
|
}
|
|
6923
|
-
return instance$
|
|
6933
|
+
return instance$7;
|
|
6924
6934
|
},
|
|
6925
6935
|
};
|
|
6926
6936
|
|
|
@@ -7497,6 +7507,108 @@ const setVisitorClientToken = async (params) => {
|
|
|
7497
7507
|
return { accessToken, users, userType };
|
|
7498
7508
|
};
|
|
7499
7509
|
|
|
7510
|
+
/* begin_public_function
|
|
7511
|
+
id: client.logout
|
|
7512
|
+
*/
|
|
7513
|
+
/**
|
|
7514
|
+
* ```js
|
|
7515
|
+
* import { Client } from '@amityco/ts-sdk-react-native';
|
|
7516
|
+
* const success = await Client.logout()
|
|
7517
|
+
* ```
|
|
7518
|
+
*
|
|
7519
|
+
* Disconnects an {@link Amity.Client} instance from ASC servers
|
|
7520
|
+
*
|
|
7521
|
+
* @returns a success boolean if disconnected
|
|
7522
|
+
*
|
|
7523
|
+
* @category Client API
|
|
7524
|
+
* @async
|
|
7525
|
+
*/
|
|
7526
|
+
const logout = async () => {
|
|
7527
|
+
var _a;
|
|
7528
|
+
const client = getActiveClient();
|
|
7529
|
+
client.log('client/api/disconnectClient');
|
|
7530
|
+
if (client.mqtt && client.mqtt.connected) {
|
|
7531
|
+
client.mqtt.disconnect();
|
|
7532
|
+
}
|
|
7533
|
+
/*
|
|
7534
|
+
* for cases when session state is terminated (example on ban) or token expired,
|
|
7535
|
+
* the terminating block will set session state to terminated or for the or
|
|
7536
|
+
* in the case of expired token the same happens
|
|
7537
|
+
*
|
|
7538
|
+
* establishing state also ignored in cases where accessTokenExpiryWatcher
|
|
7539
|
+
* calls renewal. There is a possibility that renewal will be called before
|
|
7540
|
+
* disconnectClient finishes execution
|
|
7541
|
+
*
|
|
7542
|
+
* IMPORTANT: call this before `emitter.all.clear()`, otherwise the session
|
|
7543
|
+
* event will never be triggered
|
|
7544
|
+
*/
|
|
7545
|
+
if (client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */)
|
|
7546
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
7547
|
+
client.emitter.all.clear();
|
|
7548
|
+
(_a = client.mqtt) === null || _a === void 0 ? void 0 : _a.removeAllListeners();
|
|
7549
|
+
client.userId = undefined;
|
|
7550
|
+
client.token = undefined;
|
|
7551
|
+
client.loginType = undefined;
|
|
7552
|
+
client.http.defaults.headers.common.Authorization = '';
|
|
7553
|
+
client.http.defaults.metadata = {
|
|
7554
|
+
tokenExpiry: '',
|
|
7555
|
+
isGlobalBanned: false,
|
|
7556
|
+
isUserDeleted: false,
|
|
7557
|
+
};
|
|
7558
|
+
if (typeof document !== 'undefined') {
|
|
7559
|
+
document.cookie = '_ascSession=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
|
7560
|
+
}
|
|
7561
|
+
/*
|
|
7562
|
+
* Cache should be usable if tokenExpired
|
|
7563
|
+
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#SDK-usability-based-on-Session-State
|
|
7564
|
+
*/
|
|
7565
|
+
if (client.sessionState !== "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.cache) {
|
|
7566
|
+
client.cache = { data: {} };
|
|
7567
|
+
}
|
|
7568
|
+
return true;
|
|
7569
|
+
};
|
|
7570
|
+
/* end_public_function */
|
|
7571
|
+
|
|
7572
|
+
/**
|
|
7573
|
+
* Terminates {@link Amity.Client} instance
|
|
7574
|
+
*
|
|
7575
|
+
*
|
|
7576
|
+
*
|
|
7577
|
+
* @category private
|
|
7578
|
+
*/
|
|
7579
|
+
const terminateClient = (terminationReason) => {
|
|
7580
|
+
const client = getActiveClient();
|
|
7581
|
+
setSessionState("terminated" /* Amity.SessionStates.TERMINATED */, terminationReason);
|
|
7582
|
+
if (client.http.defaults.metadata) {
|
|
7583
|
+
if (terminationReason === "globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */)
|
|
7584
|
+
client.http.defaults.metadata.isGlobalBanned = true;
|
|
7585
|
+
if (terminationReason === "userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */)
|
|
7586
|
+
client.http.defaults.metadata.isUserDeleted = true;
|
|
7587
|
+
}
|
|
7588
|
+
client.sessionHandler = undefined;
|
|
7589
|
+
logout();
|
|
7590
|
+
};
|
|
7591
|
+
|
|
7592
|
+
let currentUserType = null;
|
|
7593
|
+
/* begin_public_function
|
|
7594
|
+
id: client.get_current_user_type
|
|
7595
|
+
*/
|
|
7596
|
+
const getCurrentUserType = () => {
|
|
7597
|
+
if (!currentUserType) {
|
|
7598
|
+
throw new ASCError('Connect client first', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
|
|
7599
|
+
}
|
|
7600
|
+
return currentUserType;
|
|
7601
|
+
};
|
|
7602
|
+
/* end_public_function */
|
|
7603
|
+
const setCurrentUserType = (userType) => {
|
|
7604
|
+
currentUserType = userType;
|
|
7605
|
+
};
|
|
7606
|
+
|
|
7607
|
+
const setCurrentUser = ({ user, userType, }) => {
|
|
7608
|
+
setActiveUser(user);
|
|
7609
|
+
setCurrentUserType(userType);
|
|
7610
|
+
};
|
|
7611
|
+
|
|
7500
7612
|
const createUserEventSubscriber = (event, callback) => {
|
|
7501
7613
|
const client = getActiveClient();
|
|
7502
7614
|
const filter = (data) => {
|
|
@@ -7815,13 +7927,13 @@ class AnalyticsEngine {
|
|
|
7815
7927
|
this._eventCapturer.resetAllBuckets();
|
|
7816
7928
|
}
|
|
7817
7929
|
}
|
|
7818
|
-
let instance$
|
|
7930
|
+
let instance$6;
|
|
7819
7931
|
var AnalyticsEngine$1 = {
|
|
7820
7932
|
getInstance: () => {
|
|
7821
|
-
if (!instance$
|
|
7822
|
-
instance$
|
|
7933
|
+
if (!instance$6) {
|
|
7934
|
+
instance$6 = new AnalyticsEngine();
|
|
7823
7935
|
}
|
|
7824
|
-
return instance$
|
|
7936
|
+
return instance$6;
|
|
7825
7937
|
},
|
|
7826
7938
|
};
|
|
7827
7939
|
|
|
@@ -8049,12 +8161,12 @@ class MessageReadReceiptSyncEngine {
|
|
|
8049
8161
|
}
|
|
8050
8162
|
}
|
|
8051
8163
|
}
|
|
8052
|
-
let instance$
|
|
8164
|
+
let instance$5 = null;
|
|
8053
8165
|
var ReadReceiptSyncEngine = {
|
|
8054
8166
|
getInstance: () => {
|
|
8055
|
-
if (!instance$
|
|
8056
|
-
instance$
|
|
8057
|
-
return instance$
|
|
8167
|
+
if (!instance$5)
|
|
8168
|
+
instance$5 = new MessageReadReceiptSyncEngine();
|
|
8169
|
+
return instance$5;
|
|
8058
8170
|
},
|
|
8059
8171
|
};
|
|
8060
8172
|
|
|
@@ -8308,12 +8420,12 @@ class LegacyMessageReadReceiptSyncEngine {
|
|
|
8308
8420
|
}
|
|
8309
8421
|
}
|
|
8310
8422
|
}
|
|
8311
|
-
let instance$
|
|
8423
|
+
let instance$4 = null;
|
|
8312
8424
|
var LegacyReadReceiptSyncEngine = {
|
|
8313
8425
|
getInstance: () => {
|
|
8314
|
-
if (!instance$
|
|
8315
|
-
instance$
|
|
8316
|
-
return instance$
|
|
8426
|
+
if (!instance$4)
|
|
8427
|
+
instance$4 = new LegacyMessageReadReceiptSyncEngine();
|
|
8428
|
+
return instance$4;
|
|
8317
8429
|
},
|
|
8318
8430
|
};
|
|
8319
8431
|
|
|
@@ -8589,12 +8701,12 @@ class ObjectResolverEngine {
|
|
|
8589
8701
|
this.stopResolver();
|
|
8590
8702
|
}
|
|
8591
8703
|
}
|
|
8592
|
-
let instance$
|
|
8704
|
+
let instance$3 = null;
|
|
8593
8705
|
var ObjectResolverEngine$1 = {
|
|
8594
8706
|
getInstance: () => {
|
|
8595
|
-
if (!instance$
|
|
8596
|
-
instance$
|
|
8597
|
-
return instance$
|
|
8707
|
+
if (!instance$3)
|
|
8708
|
+
instance$3 = new ObjectResolverEngine();
|
|
8709
|
+
return instance$3;
|
|
8598
8710
|
},
|
|
8599
8711
|
};
|
|
8600
8712
|
|
|
@@ -8744,13 +8856,13 @@ class LiveReactionSyncEngine {
|
|
|
8744
8856
|
this.stopReactionsSync();
|
|
8745
8857
|
}
|
|
8746
8858
|
}
|
|
8747
|
-
let instance$
|
|
8859
|
+
let instance$2;
|
|
8748
8860
|
var ReactionSyncEngine = {
|
|
8749
8861
|
getInstance: () => {
|
|
8750
|
-
if (!instance$
|
|
8751
|
-
instance$
|
|
8862
|
+
if (!instance$2) {
|
|
8863
|
+
instance$2 = new LiveReactionSyncEngine();
|
|
8752
8864
|
}
|
|
8753
|
-
return instance$
|
|
8865
|
+
return instance$2;
|
|
8754
8866
|
},
|
|
8755
8867
|
};
|
|
8756
8868
|
|
|
@@ -8772,87 +8884,6 @@ var reactionSyncEngineOnLoginHandler = () => {
|
|
|
8772
8884
|
};
|
|
8773
8885
|
};
|
|
8774
8886
|
|
|
8775
|
-
/* begin_public_function
|
|
8776
|
-
id: client.logout
|
|
8777
|
-
*/
|
|
8778
|
-
/**
|
|
8779
|
-
* ```js
|
|
8780
|
-
* import { Client } from '@amityco/ts-sdk-react-native';
|
|
8781
|
-
* const success = await Client.logout()
|
|
8782
|
-
* ```
|
|
8783
|
-
*
|
|
8784
|
-
* Disconnects an {@link Amity.Client} instance from ASC servers
|
|
8785
|
-
*
|
|
8786
|
-
* @returns a success boolean if disconnected
|
|
8787
|
-
*
|
|
8788
|
-
* @category Client API
|
|
8789
|
-
* @async
|
|
8790
|
-
*/
|
|
8791
|
-
const logout = async () => {
|
|
8792
|
-
var _a;
|
|
8793
|
-
const client = getActiveClient();
|
|
8794
|
-
client.log('client/api/disconnectClient');
|
|
8795
|
-
if (client.mqtt && client.mqtt.connected) {
|
|
8796
|
-
client.mqtt.disconnect();
|
|
8797
|
-
}
|
|
8798
|
-
/*
|
|
8799
|
-
* for cases when session state is terminated (example on ban) or token expired,
|
|
8800
|
-
* the terminating block will set session state to terminated or for the or
|
|
8801
|
-
* in the case of expired token the same happens
|
|
8802
|
-
*
|
|
8803
|
-
* establishing state also ignored in cases where accessTokenExpiryWatcher
|
|
8804
|
-
* calls renewal. There is a possibility that renewal will be called before
|
|
8805
|
-
* disconnectClient finishes execution
|
|
8806
|
-
*
|
|
8807
|
-
* IMPORTANT: call this before `emitter.all.clear()`, otherwise the session
|
|
8808
|
-
* event will never be triggered
|
|
8809
|
-
*/
|
|
8810
|
-
if (client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */)
|
|
8811
|
-
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
8812
|
-
client.emitter.all.clear();
|
|
8813
|
-
(_a = client.mqtt) === null || _a === void 0 ? void 0 : _a.removeAllListeners();
|
|
8814
|
-
client.userId = undefined;
|
|
8815
|
-
client.token = undefined;
|
|
8816
|
-
client.http.defaults.headers.common.Authorization = '';
|
|
8817
|
-
client.http.defaults.metadata = {
|
|
8818
|
-
tokenExpiry: '',
|
|
8819
|
-
isGlobalBanned: false,
|
|
8820
|
-
isUserDeleted: false,
|
|
8821
|
-
};
|
|
8822
|
-
if (typeof document !== 'undefined') {
|
|
8823
|
-
document.cookie = '_ascSession=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
|
8824
|
-
}
|
|
8825
|
-
/*
|
|
8826
|
-
* Cache should be usable if tokenExpired
|
|
8827
|
-
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#SDK-usability-based-on-Session-State
|
|
8828
|
-
*/
|
|
8829
|
-
if (client.sessionState !== "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.cache) {
|
|
8830
|
-
client.cache = { data: {} };
|
|
8831
|
-
}
|
|
8832
|
-
return true;
|
|
8833
|
-
};
|
|
8834
|
-
/* end_public_function */
|
|
8835
|
-
|
|
8836
|
-
/**
|
|
8837
|
-
* Terminates {@link Amity.Client} instance
|
|
8838
|
-
*
|
|
8839
|
-
*
|
|
8840
|
-
*
|
|
8841
|
-
* @category private
|
|
8842
|
-
*/
|
|
8843
|
-
const terminateClient = (terminationReason) => {
|
|
8844
|
-
const client = getActiveClient();
|
|
8845
|
-
setSessionState("terminated" /* Amity.SessionStates.TERMINATED */, terminationReason);
|
|
8846
|
-
if (client.http.defaults.metadata) {
|
|
8847
|
-
if (terminationReason === "globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */)
|
|
8848
|
-
client.http.defaults.metadata.isGlobalBanned = true;
|
|
8849
|
-
if (terminationReason === "userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */)
|
|
8850
|
-
client.http.defaults.metadata.isUserDeleted = true;
|
|
8851
|
-
}
|
|
8852
|
-
client.sessionHandler = undefined;
|
|
8853
|
-
logout();
|
|
8854
|
-
};
|
|
8855
|
-
|
|
8856
8887
|
const EVENTS = [
|
|
8857
8888
|
'disconnected',
|
|
8858
8889
|
'error',
|
|
@@ -8982,24 +9013,50 @@ const removeChannelMarkerCache = (channel) => {
|
|
|
8982
9013
|
dropFromCache(['channelMarker', 'get', id], true);
|
|
8983
9014
|
};
|
|
8984
9015
|
|
|
8985
|
-
|
|
8986
|
-
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
9016
|
+
/**
|
|
9017
|
+
* Sets up all login-related event subscriptions
|
|
9018
|
+
* This includes handlers for user bans, deletions, token events, and various engine initializations
|
|
9019
|
+
*
|
|
9020
|
+
* @param unsubWatcher - The unsubscriber function for the access token expiry watcher
|
|
9021
|
+
* @returns Array of unsubscriber functions for all registered subscriptions
|
|
9022
|
+
*
|
|
9023
|
+
* @category private
|
|
9024
|
+
*/
|
|
9025
|
+
const setupLoginSubscriptions = (unsubWatcher) => {
|
|
9026
|
+
const client = getActiveClient();
|
|
9027
|
+
const subscriptions = [];
|
|
9028
|
+
subscriptions.push(
|
|
9029
|
+
// GLOBAL_BAN
|
|
9030
|
+
onClientBanned((_) => {
|
|
9031
|
+
terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
|
|
9032
|
+
subscriptions.forEach(fn => fn());
|
|
9033
|
+
unsubWatcher();
|
|
9034
|
+
}), onTokenTerminated(_ => {
|
|
9035
|
+
terminateClient();
|
|
9036
|
+
subscriptions.forEach(fn => fn());
|
|
9037
|
+
unsubWatcher();
|
|
9038
|
+
}), onUserDeleted$2((user) => {
|
|
9039
|
+
if (user.userId === client.userId) {
|
|
9040
|
+
terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
|
|
9041
|
+
subscriptions.forEach(fn => fn());
|
|
9042
|
+
unsubWatcher();
|
|
9043
|
+
}
|
|
9044
|
+
}), onTokenExpired(state => {
|
|
9045
|
+
SessionWatcher$1.getInstance().setSessionState(state);
|
|
9046
|
+
logout();
|
|
9047
|
+
subscriptions.forEach(fn => fn());
|
|
9048
|
+
}),
|
|
9049
|
+
// NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
|
|
9050
|
+
// the channel because currently backend can't handle this, so every time a user is banned from
|
|
9051
|
+
// a channel or the channel is deleted the channel's unread count will not be reset to zero
|
|
9052
|
+
onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler());
|
|
9053
|
+
if (client.useLegacyUnreadCount) {
|
|
9054
|
+
subscriptions.push(readReceiptSyncEngineOnLoginHandler());
|
|
8992
9055
|
}
|
|
8993
|
-
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
|
|
8997
|
-
currentUserType = userType;
|
|
8998
|
-
};
|
|
8999
|
-
|
|
9000
|
-
const setCurrentUser = ({ user, userType, }) => {
|
|
9001
|
-
setActiveUser(user);
|
|
9002
|
-
setCurrentUserType(userType);
|
|
9056
|
+
else {
|
|
9057
|
+
subscriptions.push(legacyReadReceiptSyncEngineOnLoginHandler());
|
|
9058
|
+
}
|
|
9059
|
+
return subscriptions;
|
|
9003
9060
|
};
|
|
9004
9061
|
|
|
9005
9062
|
/* eslint-disable no-param-reassign */
|
|
@@ -9008,8 +9065,8 @@ const setCurrentUser = ({ user, userType, }) => {
|
|
|
9008
9065
|
* than the one already connected, in which case the existing subscriptions need
|
|
9009
9066
|
* to be cleared
|
|
9010
9067
|
*/
|
|
9011
|
-
let subscriptions$
|
|
9012
|
-
async function runMqtt$
|
|
9068
|
+
let subscriptions$4 = [];
|
|
9069
|
+
async function runMqtt$2() {
|
|
9013
9070
|
await modifyMqttConnection();
|
|
9014
9071
|
}
|
|
9015
9072
|
/* begin_public_function
|
|
@@ -9043,8 +9100,8 @@ const login = async (params, sessionHandler, config) => {
|
|
|
9043
9100
|
if (client.userId && client.userId !== params.userId) {
|
|
9044
9101
|
await logout();
|
|
9045
9102
|
// Remove subscription to ban and delete
|
|
9046
|
-
subscriptions$
|
|
9047
|
-
subscriptions$
|
|
9103
|
+
subscriptions$4.forEach(fn => fn());
|
|
9104
|
+
subscriptions$4 = [];
|
|
9048
9105
|
}
|
|
9049
9106
|
// default values
|
|
9050
9107
|
const defaultDeviceId = await getDeviceId();
|
|
@@ -9069,11 +9126,12 @@ const login = async (params, sessionHandler, config) => {
|
|
|
9069
9126
|
}
|
|
9070
9127
|
client.userId = user.userId;
|
|
9071
9128
|
client.sessionHandler = sessionHandler;
|
|
9129
|
+
client.loginType = 'userId';
|
|
9072
9130
|
/*
|
|
9073
9131
|
* Cannot push to subscriptions as watcher needs to continue working even if
|
|
9074
9132
|
* token expires
|
|
9075
9133
|
*/
|
|
9076
|
-
unsubWatcher = client.accessTokenExpiryWatcher(
|
|
9134
|
+
unsubWatcher = client.accessTokenExpiryWatcher();
|
|
9077
9135
|
setCurrentUser({ user, userType });
|
|
9078
9136
|
}
|
|
9079
9137
|
catch (error) {
|
|
@@ -9086,40 +9144,11 @@ const login = async (params, sessionHandler, config) => {
|
|
|
9086
9144
|
throw error;
|
|
9087
9145
|
}
|
|
9088
9146
|
if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
|
|
9089
|
-
runMqtt$
|
|
9147
|
+
runMqtt$2();
|
|
9090
9148
|
}
|
|
9091
9149
|
await initializeMessagePreviewSetting();
|
|
9092
|
-
if (subscriptions$
|
|
9093
|
-
subscriptions$
|
|
9094
|
-
// GLOBAL_BAN
|
|
9095
|
-
onClientBanned((_) => {
|
|
9096
|
-
terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
|
|
9097
|
-
subscriptions$3.forEach(fn => fn());
|
|
9098
|
-
unsubWatcher();
|
|
9099
|
-
}), onTokenTerminated(_ => {
|
|
9100
|
-
terminateClient();
|
|
9101
|
-
subscriptions$3.forEach(fn => fn());
|
|
9102
|
-
unsubWatcher();
|
|
9103
|
-
}), onUserDeleted$2((user) => {
|
|
9104
|
-
if (user.userId === client.userId) {
|
|
9105
|
-
terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
|
|
9106
|
-
subscriptions$3.forEach(fn => fn());
|
|
9107
|
-
unsubWatcher();
|
|
9108
|
-
}
|
|
9109
|
-
}), onTokenExpired(state => {
|
|
9110
|
-
SessionWatcher$1.getInstance().setSessionState(state);
|
|
9111
|
-
logout();
|
|
9112
|
-
subscriptions$3.forEach(fn => fn());
|
|
9113
|
-
}),
|
|
9114
|
-
// NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
|
|
9115
|
-
// the channel because currently backend can't handle this, so every time a user is banned from
|
|
9116
|
-
// a channel or the channel is deleted the channel's unread count will not be reset to zero
|
|
9117
|
-
onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler());
|
|
9118
|
-
if (client.useLegacyUnreadCount) {
|
|
9119
|
-
subscriptions$3.push(readReceiptSyncEngineOnLoginHandler());
|
|
9120
|
-
}
|
|
9121
|
-
else
|
|
9122
|
-
subscriptions$3.push(legacyReadReceiptSyncEngineOnLoginHandler());
|
|
9150
|
+
if (subscriptions$4.length === 0) {
|
|
9151
|
+
subscriptions$4 = setupLoginSubscriptions(unsubWatcher);
|
|
9123
9152
|
}
|
|
9124
9153
|
return true;
|
|
9125
9154
|
};
|
|
@@ -9131,7 +9160,7 @@ const login = async (params, sessionHandler, config) => {
|
|
|
9131
9160
|
* than the one already connected, in which case the existing subscriptions need
|
|
9132
9161
|
* to be cleared
|
|
9133
9162
|
*/
|
|
9134
|
-
const subscriptions$
|
|
9163
|
+
const subscriptions$3 = [];
|
|
9135
9164
|
/* begin_public_function
|
|
9136
9165
|
id: client.loginAsVisitor
|
|
9137
9166
|
*/
|
|
@@ -9174,11 +9203,12 @@ const loginAsVisitor = async (params) => {
|
|
|
9174
9203
|
[user] = users;
|
|
9175
9204
|
client.userId = user.userId;
|
|
9176
9205
|
client.sessionHandler = params.sessionHandler;
|
|
9206
|
+
client.loginType = 'userId';
|
|
9177
9207
|
/*
|
|
9178
9208
|
* Cannot push to subscriptions as watcher needs to continue working even if
|
|
9179
9209
|
* token expires
|
|
9180
9210
|
*/
|
|
9181
|
-
unsubWatcher = client.accessTokenExpiryWatcher(
|
|
9211
|
+
unsubWatcher = client.accessTokenExpiryWatcher();
|
|
9182
9212
|
setCurrentUser({ user, userType });
|
|
9183
9213
|
}
|
|
9184
9214
|
catch (error) {
|
|
@@ -9191,16 +9221,16 @@ const loginAsVisitor = async (params) => {
|
|
|
9191
9221
|
throw error;
|
|
9192
9222
|
}
|
|
9193
9223
|
await initializeMessagePreviewSetting();
|
|
9194
|
-
if (subscriptions$
|
|
9224
|
+
if (subscriptions$3.length === 0) {
|
|
9195
9225
|
// handling internal SDK events
|
|
9196
|
-
subscriptions$
|
|
9226
|
+
subscriptions$3.push(onTokenTerminated(_ => {
|
|
9197
9227
|
terminateClient();
|
|
9198
|
-
subscriptions$
|
|
9228
|
+
subscriptions$3.forEach(fn => fn());
|
|
9199
9229
|
unsubWatcher();
|
|
9200
9230
|
}), onTokenExpired(state => {
|
|
9201
9231
|
SessionWatcher$1.getInstance().setSessionState(state);
|
|
9202
9232
|
logout();
|
|
9203
|
-
subscriptions$
|
|
9233
|
+
subscriptions$3.forEach(fn => fn());
|
|
9204
9234
|
}));
|
|
9205
9235
|
}
|
|
9206
9236
|
return true;
|
|
@@ -9229,7 +9259,7 @@ const renewal = () => {
|
|
|
9229
9259
|
* Per instance of Renewal, only one renewal is allowed
|
|
9230
9260
|
*/
|
|
9231
9261
|
const renewToken = async (authToken) => {
|
|
9232
|
-
const { userId, displayName } =
|
|
9262
|
+
const { userId, displayName } = getActiveUser();
|
|
9233
9263
|
const deviceId = await getDeviceId();
|
|
9234
9264
|
const params = { userId, displayName, authToken, deviceId };
|
|
9235
9265
|
if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.sessionHandler) {
|
|
@@ -9304,6 +9334,242 @@ const renewal = () => {
|
|
|
9304
9334
|
};
|
|
9305
9335
|
/* end_public_function */
|
|
9306
9336
|
|
|
9337
|
+
const validateAccessToken = async ({ token, userId }) => {
|
|
9338
|
+
const client = getActiveClient();
|
|
9339
|
+
// Validate token using sessions API
|
|
9340
|
+
await client.http.get('/api/v3/sessions', {
|
|
9341
|
+
headers: {
|
|
9342
|
+
Authorization: `Bearer ${token.accessToken}`,
|
|
9343
|
+
},
|
|
9344
|
+
});
|
|
9345
|
+
// Get user details
|
|
9346
|
+
const { data: { users }, } = await client.http.get(`/api/v3/users/${userId}`, {
|
|
9347
|
+
headers: {
|
|
9348
|
+
Authorization: `Bearer ${token.accessToken}`,
|
|
9349
|
+
},
|
|
9350
|
+
});
|
|
9351
|
+
const user = users.find((u) => u.userId === userId);
|
|
9352
|
+
client.http.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
|
|
9353
|
+
client.http.defaults.metadata = {
|
|
9354
|
+
tokenExpiry: token.expiresAt,
|
|
9355
|
+
isGlobalBanned: false,
|
|
9356
|
+
isUserDeleted: false,
|
|
9357
|
+
};
|
|
9358
|
+
client.upload.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
|
|
9359
|
+
client.upload.defaults.metadata = {
|
|
9360
|
+
tokenExpiry: token.expiresAt,
|
|
9361
|
+
isGlobalBanned: false,
|
|
9362
|
+
isUserDeleted: false,
|
|
9363
|
+
};
|
|
9364
|
+
client.token = token;
|
|
9365
|
+
return user;
|
|
9366
|
+
};
|
|
9367
|
+
|
|
9368
|
+
const isSameUserId = (token) => {
|
|
9369
|
+
var _a;
|
|
9370
|
+
const client = getActiveClient();
|
|
9371
|
+
const decoded = jwtDecode__default["default"](token);
|
|
9372
|
+
return ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) === client.userId;
|
|
9373
|
+
};
|
|
9374
|
+
|
|
9375
|
+
let subscriptions$2 = [];
|
|
9376
|
+
async function runMqtt$1() {
|
|
9377
|
+
await modifyMqttConnection();
|
|
9378
|
+
}
|
|
9379
|
+
/* begin_public_function
|
|
9380
|
+
id: client.loginWithAccessToken
|
|
9381
|
+
*/
|
|
9382
|
+
/**
|
|
9383
|
+
* ```js
|
|
9384
|
+
* import { loginWithAccessToken } from '@amityco/ts-sdk'
|
|
9385
|
+
* const success = await loginWithAccessToken('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...')
|
|
9386
|
+
* ```
|
|
9387
|
+
*
|
|
9388
|
+
* Authenticates a user using a pre-existing access token, allowing direct login without user credentials.
|
|
9389
|
+
* Designed for customers who manage access tokens on their own backend.
|
|
9390
|
+
*
|
|
9391
|
+
* @param accessToken JWT access token signed by customer's backend containing user identity
|
|
9392
|
+
* @returns true if authentication is successful
|
|
9393
|
+
*
|
|
9394
|
+
* @category Client API
|
|
9395
|
+
* @async
|
|
9396
|
+
*/
|
|
9397
|
+
const loginWithAccessToken = async (accessToken) => {
|
|
9398
|
+
var _a, _b;
|
|
9399
|
+
const client = getActiveClient();
|
|
9400
|
+
let unsubWatcher;
|
|
9401
|
+
client.log('client/api/loginWithAccessToken', {
|
|
9402
|
+
apiKey: client.apiKey,
|
|
9403
|
+
sessionState: client.sessionState,
|
|
9404
|
+
});
|
|
9405
|
+
// Validate input
|
|
9406
|
+
if (!accessToken || typeof accessToken !== 'string' || accessToken.trim() === '') {
|
|
9407
|
+
throw new ASCError('Access token must be a non-empty string', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9408
|
+
}
|
|
9409
|
+
let decoded;
|
|
9410
|
+
try {
|
|
9411
|
+
decoded = jwtDecode__default["default"](accessToken);
|
|
9412
|
+
}
|
|
9413
|
+
catch (error) {
|
|
9414
|
+
throw new ASCError('Invalid access token format', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9415
|
+
}
|
|
9416
|
+
// Extract userId from token
|
|
9417
|
+
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);
|
|
9418
|
+
if (!userId) {
|
|
9419
|
+
throw new ASCError('Access token does not contain userId', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9420
|
+
}
|
|
9421
|
+
// Handle existing connected user
|
|
9422
|
+
if (client.userId) {
|
|
9423
|
+
const sameUser = isSameUserId(accessToken);
|
|
9424
|
+
if (!sameUser) {
|
|
9425
|
+
// Different user - do full logout
|
|
9426
|
+
await logout();
|
|
9427
|
+
}
|
|
9428
|
+
}
|
|
9429
|
+
try {
|
|
9430
|
+
// Set state to establishing
|
|
9431
|
+
setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
|
|
9432
|
+
// Prepare token object for validation
|
|
9433
|
+
const tokenObject = {
|
|
9434
|
+
accessToken,
|
|
9435
|
+
issuedAt: decoded.iat ? new Date(decoded.iat * 1000).toISOString() : new Date().toISOString(),
|
|
9436
|
+
expiresAt: new Date(decoded.exp * 1000).toISOString(),
|
|
9437
|
+
};
|
|
9438
|
+
// Validate token and get user
|
|
9439
|
+
const user = await validateAccessToken({
|
|
9440
|
+
token: tokenObject,
|
|
9441
|
+
userId,
|
|
9442
|
+
});
|
|
9443
|
+
if (user == null) {
|
|
9444
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
9445
|
+
throw new ASCError(`User ${userId} has not been found`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9446
|
+
}
|
|
9447
|
+
if (user.isDeleted) {
|
|
9448
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
9449
|
+
throw new ASCError(`User ${userId} has been deleted`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9450
|
+
}
|
|
9451
|
+
if (user.isGlobalBanned) {
|
|
9452
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
9453
|
+
throw new ASCError(`User ${userId} is globally banned`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9454
|
+
}
|
|
9455
|
+
// Set userId and login method flag
|
|
9456
|
+
client.userId = user.userId;
|
|
9457
|
+
// Set login method flag to 'accessToken' in platform-specific login session
|
|
9458
|
+
client.loginType = 'accessToken';
|
|
9459
|
+
// This will be used by the access token handler to determine if token renewal should be invoked
|
|
9460
|
+
// Set active user
|
|
9461
|
+
setActiveUser(user);
|
|
9462
|
+
unsubWatcher = client.accessTokenExpiryWatcher();
|
|
9463
|
+
setSessionState("established" /* Amity.SessionStates.ESTABLISHED */);
|
|
9464
|
+
}
|
|
9465
|
+
catch (error) {
|
|
9466
|
+
// If error occurs, revert session state to not logged in
|
|
9467
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
9468
|
+
// Re-throw if it's already an ASCError
|
|
9469
|
+
if (error instanceof ASCError) {
|
|
9470
|
+
throw error;
|
|
9471
|
+
}
|
|
9472
|
+
// Wrap other errors
|
|
9473
|
+
throw new ASCError((error instanceof Error ? error.message : undefined) || 'Login with access token failed', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9474
|
+
}
|
|
9475
|
+
runMqtt$1();
|
|
9476
|
+
await initializeMessagePreviewSetting();
|
|
9477
|
+
if (subscriptions$2.length === 0) {
|
|
9478
|
+
subscriptions$2 = setupLoginSubscriptions(unsubWatcher);
|
|
9479
|
+
}
|
|
9480
|
+
return true;
|
|
9481
|
+
};
|
|
9482
|
+
/* end_public_function */
|
|
9483
|
+
|
|
9484
|
+
/* begin_public_function
|
|
9485
|
+
id: client.renew_with_accessToken
|
|
9486
|
+
*/
|
|
9487
|
+
/*
|
|
9488
|
+
* Renewal defintion accepted by SessionHandler interface
|
|
9489
|
+
*
|
|
9490
|
+
* Tech Spec:
|
|
9491
|
+
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Session-Handler
|
|
9492
|
+
*
|
|
9493
|
+
* @category private
|
|
9494
|
+
*/
|
|
9495
|
+
const renewWithAccessToken = async (accessToken) => {
|
|
9496
|
+
var _a, _b;
|
|
9497
|
+
const client = getActiveClient();
|
|
9498
|
+
client.log('initiating access token renewal');
|
|
9499
|
+
/*
|
|
9500
|
+
* Renews a token if it is hasn't been renewed before. Also marks token as
|
|
9501
|
+
* renewed once done
|
|
9502
|
+
* Per instance of Renewal, only one renewal is allowed
|
|
9503
|
+
*/
|
|
9504
|
+
// Validate input
|
|
9505
|
+
if (!accessToken || typeof accessToken !== 'string' || accessToken.trim() === '') {
|
|
9506
|
+
throw new ASCError('Access token must be a non-empty string', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9507
|
+
}
|
|
9508
|
+
let decoded;
|
|
9509
|
+
try {
|
|
9510
|
+
decoded = jwtDecode__default["default"](accessToken);
|
|
9511
|
+
}
|
|
9512
|
+
catch (error) {
|
|
9513
|
+
throw new ASCError('Invalid access token format', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9514
|
+
}
|
|
9515
|
+
// Extract userId from token
|
|
9516
|
+
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);
|
|
9517
|
+
if (!userId) {
|
|
9518
|
+
throw new ASCError('Access token does not contain userId', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9519
|
+
}
|
|
9520
|
+
// Handle existing connected user
|
|
9521
|
+
if (client.userId) {
|
|
9522
|
+
const sameUser = isSameUserId(accessToken);
|
|
9523
|
+
if (!sameUser) {
|
|
9524
|
+
// Different user - do full logout
|
|
9525
|
+
await logout();
|
|
9526
|
+
}
|
|
9527
|
+
}
|
|
9528
|
+
const tokenObject = {
|
|
9529
|
+
accessToken,
|
|
9530
|
+
issuedAt: decoded.iat ? new Date(decoded.iat * 1000).toISOString() : new Date().toISOString(),
|
|
9531
|
+
expiresAt: new Date(decoded.exp * 1000).toISOString(),
|
|
9532
|
+
};
|
|
9533
|
+
if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.sessionHandler) {
|
|
9534
|
+
await loginWithAccessToken(accessToken);
|
|
9535
|
+
}
|
|
9536
|
+
else {
|
|
9537
|
+
// about to expire
|
|
9538
|
+
await validateAccessToken({
|
|
9539
|
+
token: tokenObject,
|
|
9540
|
+
userId,
|
|
9541
|
+
});
|
|
9542
|
+
}
|
|
9543
|
+
};
|
|
9544
|
+
/* end_public_function */
|
|
9545
|
+
|
|
9546
|
+
/**
|
|
9547
|
+
* Helper function to renew access token using the accessTokenHandler
|
|
9548
|
+
* Handles error catching and logging
|
|
9549
|
+
*
|
|
9550
|
+
* @param useScheduledTask - Whether to wrap renewal in scheduleTask (for token expired case)
|
|
9551
|
+
* @category private
|
|
9552
|
+
*/
|
|
9553
|
+
const renewTokenWithHandler = async ({ useScheduledTask = false, }) => {
|
|
9554
|
+
const client = getActiveClient();
|
|
9555
|
+
if (!client.userId || !client.accessTokenHandler) {
|
|
9556
|
+
return;
|
|
9557
|
+
}
|
|
9558
|
+
try {
|
|
9559
|
+
const newToken = await client.accessTokenHandler.onTokenRenew(client.userId);
|
|
9560
|
+
if (useScheduledTask) {
|
|
9561
|
+
scheduleTask(() => renewWithAccessToken(newToken));
|
|
9562
|
+
}
|
|
9563
|
+
else {
|
|
9564
|
+
renewWithAccessToken(newToken);
|
|
9565
|
+
}
|
|
9566
|
+
}
|
|
9567
|
+
catch (error) {
|
|
9568
|
+
client.log('Proactive token renewal failed, will retry when token expires', error);
|
|
9569
|
+
// Will fallback to expired token flow
|
|
9570
|
+
}
|
|
9571
|
+
};
|
|
9572
|
+
|
|
9307
9573
|
const ABOUT_TO_EXPIRE_THRESHOLD = 80 / 100;
|
|
9308
9574
|
const COMPENSATED_DELAY = 5 * MINUTE;
|
|
9309
9575
|
/*
|
|
@@ -9339,10 +9605,11 @@ const isAboutToExpire = (params) => {
|
|
|
9339
9605
|
*
|
|
9340
9606
|
* @category private
|
|
9341
9607
|
*/
|
|
9342
|
-
const accessTokenExpiryWatcher = (
|
|
9343
|
-
const interval = setInterval(() => {
|
|
9608
|
+
const accessTokenExpiryWatcher = () => {
|
|
9609
|
+
const interval = setInterval(async () => {
|
|
9344
9610
|
const client = getActiveClient();
|
|
9345
|
-
|
|
9611
|
+
const { sessionHandler, accessTokenHandler, loginType } = client;
|
|
9612
|
+
if (!client.token || !client.userId)
|
|
9346
9613
|
return;
|
|
9347
9614
|
const { issuedAt, expiresAt } = client.token;
|
|
9348
9615
|
if (isExpired(expiresAt)) {
|
|
@@ -9353,18 +9620,38 @@ const accessTokenExpiryWatcher = (sessionHandler) => {
|
|
|
9353
9620
|
*/
|
|
9354
9621
|
fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
|
|
9355
9622
|
/*
|
|
9356
|
-
*
|
|
9357
|
-
*
|
|
9358
|
-
*
|
|
9359
|
-
* Since fireEvent is scheduled, it will be called
|
|
9360
|
-
* after sessionHandler leading to an invalid state change from
|
|
9361
|
-
* establishing to tokenExpired
|
|
9623
|
+
* Check loginType to determine which handler to use:
|
|
9624
|
+
* - 'accessToken' = use accessTokenHandler
|
|
9625
|
+
* - 'userId' = use sessionHandler
|
|
9362
9626
|
*/
|
|
9363
|
-
|
|
9627
|
+
if (loginType === 'accessToken' && accessTokenHandler) {
|
|
9628
|
+
await renewTokenWithHandler({ useScheduledTask: false });
|
|
9629
|
+
}
|
|
9630
|
+
else if (loginType === 'userId' && sessionHandler) {
|
|
9631
|
+
/*
|
|
9632
|
+
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Automatically-initiate-renewal-flow
|
|
9633
|
+
*
|
|
9634
|
+
* Why scheduled task?
|
|
9635
|
+
* Since fireEvent is scheduled, it will be called
|
|
9636
|
+
* after sessionHandler leading to an invalid state change from
|
|
9637
|
+
* establishing to tokenExpired
|
|
9638
|
+
*/
|
|
9639
|
+
scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
|
|
9640
|
+
}
|
|
9364
9641
|
return;
|
|
9365
9642
|
}
|
|
9366
9643
|
if (isAboutToExpire({ expiresAt, issuedAt })) {
|
|
9367
|
-
|
|
9644
|
+
/*
|
|
9645
|
+
* Check loginType to determine which handler to use for proactive renewal:
|
|
9646
|
+
* - 'accessToken' = use accessTokenHandler
|
|
9647
|
+
* - 'userId' = use sessionHandler
|
|
9648
|
+
*/
|
|
9649
|
+
if (loginType === 'accessToken' && accessTokenHandler) {
|
|
9650
|
+
await renewTokenWithHandler({ useScheduledTask: false });
|
|
9651
|
+
}
|
|
9652
|
+
else if (loginType === 'userId' && sessionHandler) {
|
|
9653
|
+
sessionHandler.sessionWillRenewAccessToken(renewal());
|
|
9654
|
+
}
|
|
9368
9655
|
}
|
|
9369
9656
|
}, ACCESS_TOKEN_WATCHER_INTERVAL);
|
|
9370
9657
|
return () => clearInterval(interval);
|
|
@@ -9918,6 +10205,7 @@ const secureLogout = async () => {
|
|
|
9918
10205
|
};
|
|
9919
10206
|
/* end_public_function */
|
|
9920
10207
|
|
|
10208
|
+
/* eslint-disable no-param-reassign */
|
|
9921
10209
|
/*
|
|
9922
10210
|
* declared earlier to accomodate case when logging in with a different user
|
|
9923
10211
|
* than the one already connected, in which case the existing subscriptions need
|
|
@@ -9927,38 +10215,6 @@ let subscriptions$1 = [];
|
|
|
9927
10215
|
async function runMqtt() {
|
|
9928
10216
|
await modifyMqttConnection();
|
|
9929
10217
|
}
|
|
9930
|
-
const isSameUserId = (token) => {
|
|
9931
|
-
var _a;
|
|
9932
|
-
const client = getActiveClient();
|
|
9933
|
-
const decoded = jwtDecode__default["default"](token);
|
|
9934
|
-
return ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) === client.userId;
|
|
9935
|
-
};
|
|
9936
|
-
const validateAccessToken = async ({ token, userId }) => {
|
|
9937
|
-
const client = getActiveClient();
|
|
9938
|
-
// begin establishing session
|
|
9939
|
-
setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
|
|
9940
|
-
const { data: { users }, } = await client.http.get(`/api/v3/users/${userId}`, {
|
|
9941
|
-
headers: {
|
|
9942
|
-
Authorization: `Bearer ${token.accessToken}`,
|
|
9943
|
-
},
|
|
9944
|
-
});
|
|
9945
|
-
const user = users.find((u) => u.userId === userId);
|
|
9946
|
-
client.http.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
|
|
9947
|
-
client.http.defaults.metadata = {
|
|
9948
|
-
tokenExpiry: token.expiresAt,
|
|
9949
|
-
isGlobalBanned: false,
|
|
9950
|
-
isUserDeleted: false,
|
|
9951
|
-
};
|
|
9952
|
-
client.upload.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
|
|
9953
|
-
client.upload.defaults.metadata = {
|
|
9954
|
-
tokenExpiry: token.expiresAt,
|
|
9955
|
-
isGlobalBanned: false,
|
|
9956
|
-
isUserDeleted: false,
|
|
9957
|
-
};
|
|
9958
|
-
client.token = token;
|
|
9959
|
-
setSessionState("established" /* Amity.SessionStates.ESTABLISHED */);
|
|
9960
|
-
return user;
|
|
9961
|
-
};
|
|
9962
10218
|
/* begin_public_function
|
|
9963
10219
|
id: client.resumeSession
|
|
9964
10220
|
*/
|
|
@@ -10007,6 +10263,7 @@ const resumeSession = async (params, sessionHandler, config) => {
|
|
|
10007
10263
|
}
|
|
10008
10264
|
}
|
|
10009
10265
|
try {
|
|
10266
|
+
setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
|
|
10010
10267
|
const user = await validateAccessToken(params);
|
|
10011
10268
|
if (user == null) {
|
|
10012
10269
|
throw new ASCError(`${params.userId} has not been found`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
@@ -10113,13 +10370,13 @@ class GlobalFileAccessType {
|
|
|
10113
10370
|
}
|
|
10114
10371
|
}
|
|
10115
10372
|
_GlobalFileAccessType_fileAccessType = new WeakMap();
|
|
10116
|
-
let instance;
|
|
10373
|
+
let instance$1;
|
|
10117
10374
|
var GlobalFileAccessType$1 = {
|
|
10118
10375
|
getInstance: () => {
|
|
10119
|
-
if (!instance) {
|
|
10120
|
-
instance = new GlobalFileAccessType();
|
|
10376
|
+
if (!instance$1) {
|
|
10377
|
+
instance$1 = new GlobalFileAccessType();
|
|
10121
10378
|
}
|
|
10122
|
-
return instance;
|
|
10379
|
+
return instance$1;
|
|
10123
10380
|
},
|
|
10124
10381
|
};
|
|
10125
10382
|
|
|
@@ -10334,11 +10591,12 @@ const loginAsBot = async (params) => {
|
|
|
10334
10591
|
[user] = users;
|
|
10335
10592
|
client.userId = user.userId;
|
|
10336
10593
|
client.sessionHandler = params.sessionHandler;
|
|
10594
|
+
client.loginType = 'userId';
|
|
10337
10595
|
/*
|
|
10338
10596
|
* Cannot push to subscriptions as watcher needs to continue working even if
|
|
10339
10597
|
* token expires
|
|
10340
10598
|
*/
|
|
10341
|
-
unsubWatcher = client.accessTokenExpiryWatcher(
|
|
10599
|
+
unsubWatcher = client.accessTokenExpiryWatcher();
|
|
10342
10600
|
setCurrentUser({ user, userType });
|
|
10343
10601
|
}
|
|
10344
10602
|
catch (error) {
|
|
@@ -10367,6 +10625,53 @@ const loginAsBot = async (params) => {
|
|
|
10367
10625
|
};
|
|
10368
10626
|
/* end_public_function */
|
|
10369
10627
|
|
|
10628
|
+
/* begin_public_function
|
|
10629
|
+
id: client.setAccessTokenHandler
|
|
10630
|
+
*/
|
|
10631
|
+
/**
|
|
10632
|
+
* ```js
|
|
10633
|
+
* import { setAccessTokenHandler } from '@amityco/ts-sdk'
|
|
10634
|
+
*
|
|
10635
|
+
* const tokenHandler = {
|
|
10636
|
+
* async onTokenRenew() {
|
|
10637
|
+
* const response = await fetch('https://your-backend.com/api/refresh-token', {
|
|
10638
|
+
* method: 'POST',
|
|
10639
|
+
* credentials: 'include',
|
|
10640
|
+
* });
|
|
10641
|
+
* const data = await response.json();
|
|
10642
|
+
* return data.accessToken;
|
|
10643
|
+
* }
|
|
10644
|
+
* };
|
|
10645
|
+
*
|
|
10646
|
+
* setAccessTokenHandler(tokenHandler);
|
|
10647
|
+
* ```
|
|
10648
|
+
*
|
|
10649
|
+
* Registers a custom handler for managing access token renewal and expiration events.
|
|
10650
|
+
* This enables automatic token refresh and graceful handling of expired tokens.
|
|
10651
|
+
*
|
|
10652
|
+
* Must be called before loginWithAccessToken() to ensure the handler is available
|
|
10653
|
+
* when token expiry is detected.
|
|
10654
|
+
*
|
|
10655
|
+
* @param accessTokenHandler Handler object implementing token renewal callbacks
|
|
10656
|
+
* @returns void
|
|
10657
|
+
*
|
|
10658
|
+
* @category Client API
|
|
10659
|
+
*/
|
|
10660
|
+
const setAccessTokenHandler = (accessTokenHandler) => {
|
|
10661
|
+
const client = getActiveClient();
|
|
10662
|
+
client.log('client/api/setAccessTokenHandler', {
|
|
10663
|
+
apiKey: client.apiKey,
|
|
10664
|
+
sessionState: client.sessionState,
|
|
10665
|
+
hasOnTokenRenew: typeof (accessTokenHandler === null || accessTokenHandler === void 0 ? void 0 : accessTokenHandler.onTokenRenew) === 'function',
|
|
10666
|
+
});
|
|
10667
|
+
// Validate handler has required method
|
|
10668
|
+
if (!accessTokenHandler || typeof accessTokenHandler.onTokenRenew !== 'function') {
|
|
10669
|
+
throw new Error('AccessTokenHandler must implement onTokenRenew() method');
|
|
10670
|
+
}
|
|
10671
|
+
// Register the handler
|
|
10672
|
+
client.accessTokenHandler = accessTokenHandler;
|
|
10673
|
+
};
|
|
10674
|
+
|
|
10370
10675
|
/**
|
|
10371
10676
|
* ```js
|
|
10372
10677
|
* import { onChannelMarkerFetched } from '@amityco/ts-sdk-react-native'
|
|
@@ -10726,6 +11031,7 @@ var index$r = /*#__PURE__*/Object.freeze({
|
|
|
10726
11031
|
setActiveUser: setActiveUser,
|
|
10727
11032
|
createClient: createClient,
|
|
10728
11033
|
login: login,
|
|
11034
|
+
loginWithAccessToken: loginWithAccessToken,
|
|
10729
11035
|
logout: logout,
|
|
10730
11036
|
secureLogout: secureLogout,
|
|
10731
11037
|
resumeSession: resumeSession,
|
|
@@ -10747,6 +11053,7 @@ var index$r = /*#__PURE__*/Object.freeze({
|
|
|
10747
11053
|
getCurrentUser: getCurrentUser,
|
|
10748
11054
|
getCurrentUserType: getCurrentUserType,
|
|
10749
11055
|
setCurrentUserType: setCurrentUserType,
|
|
11056
|
+
setAccessTokenHandler: setAccessTokenHandler,
|
|
10750
11057
|
onConnectionError: onConnectionError,
|
|
10751
11058
|
onClientDisconnected: onClientDisconnected,
|
|
10752
11059
|
onClientBanned: onClientBanned,
|
|
@@ -17104,33 +17411,186 @@ removeReaction.optimistically = (referenceType, referenceId, reactionName) => {
|
|
|
17104
17411
|
return !((_d = reaction === null || reaction === void 0 ? void 0 : reaction.myReactions) === null || _d === void 0 ? void 0 : _d.includes(reactionName));
|
|
17105
17412
|
};
|
|
17106
17413
|
|
|
17107
|
-
|
|
17108
|
-
|
|
17109
|
-
|
|
17110
|
-
|
|
17111
|
-
|
|
17112
|
-
}
|
|
17113
|
-
|
|
17114
|
-
|
|
17115
|
-
|
|
17116
|
-
|
|
17117
|
-
|
|
17118
|
-
|
|
17119
|
-
|
|
17120
|
-
|
|
17121
|
-
}
|
|
17122
|
-
|
|
17123
|
-
|
|
17414
|
+
class ResetTask {
|
|
17415
|
+
constructor(postId, latestCreatedAt, serverCommentCount) {
|
|
17416
|
+
this.postId = postId;
|
|
17417
|
+
this.latestCreatedAt = latestCreatedAt;
|
|
17418
|
+
this.serverCommentCount = serverCommentCount;
|
|
17419
|
+
}
|
|
17420
|
+
}
|
|
17421
|
+
|
|
17422
|
+
// Task to track comment creation
|
|
17423
|
+
class CreateTask {
|
|
17424
|
+
constructor(postId, commentId, createdAt) {
|
|
17425
|
+
this.postId = postId;
|
|
17426
|
+
this.commentId = commentId;
|
|
17427
|
+
this.createdAt = createdAt;
|
|
17428
|
+
}
|
|
17429
|
+
}
|
|
17430
|
+
|
|
17431
|
+
// Task to track comment deletion
|
|
17432
|
+
class DeleteTask {
|
|
17433
|
+
constructor(postId, commentId) {
|
|
17434
|
+
this.postId = postId;
|
|
17435
|
+
this.commentId = commentId;
|
|
17436
|
+
}
|
|
17437
|
+
}
|
|
17438
|
+
|
|
17439
|
+
class CommentChange {
|
|
17440
|
+
constructor(latestCreatedAt, serverCommentCount) {
|
|
17441
|
+
this.latestCommentCreatedAt = latestCreatedAt;
|
|
17442
|
+
this.serverCommentCount = serverCommentCount;
|
|
17443
|
+
this.createdCommentIds = new Set();
|
|
17444
|
+
this.deletedCommentIds = new Set();
|
|
17445
|
+
}
|
|
17446
|
+
}
|
|
17447
|
+
|
|
17448
|
+
class PostCommentCountEngine {
|
|
17449
|
+
constructor() {
|
|
17450
|
+
this.isProcessing = false;
|
|
17451
|
+
this.tasks = [];
|
|
17452
|
+
this.commentChangeTracker = new Map();
|
|
17453
|
+
}
|
|
17454
|
+
queueCommentChangeTask(task) {
|
|
17455
|
+
this.tasks.push(task);
|
|
17456
|
+
if (!this.isProcessing) {
|
|
17457
|
+
this.processCommentChangeTask();
|
|
17458
|
+
}
|
|
17459
|
+
}
|
|
17460
|
+
processCommentChangeTask() {
|
|
17461
|
+
if (this.isProcessing) {
|
|
17462
|
+
return;
|
|
17463
|
+
}
|
|
17464
|
+
this.isProcessing = true;
|
|
17465
|
+
if (this.tasks.length === 0) {
|
|
17466
|
+
this.isProcessing = false;
|
|
17467
|
+
return;
|
|
17468
|
+
}
|
|
17469
|
+
// Process in capped batches, coalescing updates
|
|
17470
|
+
const batch = this.tasks.splice(0, PostCommentCountEngine.BATCH_SIZE);
|
|
17471
|
+
const modifiedPostIds = new Set();
|
|
17472
|
+
batch.forEach(task => {
|
|
17473
|
+
let modified = false;
|
|
17474
|
+
if (task instanceof ResetTask) {
|
|
17475
|
+
modified = this.processResetTaskInternal(task);
|
|
17476
|
+
}
|
|
17477
|
+
else if (task instanceof CreateTask) {
|
|
17478
|
+
modified = this.processCreateTaskInternal(task);
|
|
17479
|
+
}
|
|
17480
|
+
else if (task instanceof DeleteTask) {
|
|
17481
|
+
modified = this.processDeleteTaskInternal(task);
|
|
17482
|
+
}
|
|
17483
|
+
if (modified) {
|
|
17484
|
+
modifiedPostIds.add(task.postId);
|
|
17485
|
+
}
|
|
17486
|
+
});
|
|
17487
|
+
// Publish one update per modified post
|
|
17488
|
+
modifiedPostIds.forEach(postId => {
|
|
17489
|
+
const count = this.computeCommentCount(postId);
|
|
17490
|
+
PostCommentCountEngine.publishUpdate(postId, count);
|
|
17491
|
+
});
|
|
17492
|
+
this.isProcessing = false;
|
|
17493
|
+
// Recurse if more tasks remain
|
|
17494
|
+
if (this.tasks.length > 0) {
|
|
17495
|
+
this.processCommentChangeTask();
|
|
17496
|
+
}
|
|
17497
|
+
}
|
|
17498
|
+
processResetTaskInternal(task) {
|
|
17499
|
+
// Always creates/overwrites tracker
|
|
17500
|
+
this.commentChangeTracker.set(task.postId, new CommentChange(task.latestCreatedAt, task.serverCommentCount));
|
|
17501
|
+
return true;
|
|
17502
|
+
}
|
|
17503
|
+
processCreateTaskInternal(task) {
|
|
17504
|
+
const tracker = this.commentChangeTracker.get(task.postId);
|
|
17505
|
+
if (!tracker)
|
|
17506
|
+
return false; // No tracker, skip
|
|
17507
|
+
if (tracker.createdCommentIds.has(task.commentId))
|
|
17508
|
+
return false; // Deduplication
|
|
17509
|
+
if (task.createdAt <= tracker.latestCommentCreatedAt)
|
|
17510
|
+
return false; // Timestamp filtering
|
|
17511
|
+
tracker.createdCommentIds.add(task.commentId);
|
|
17512
|
+
return true;
|
|
17513
|
+
}
|
|
17514
|
+
processDeleteTaskInternal(task) {
|
|
17515
|
+
const tracker = this.commentChangeTracker.get(task.postId);
|
|
17516
|
+
if (!tracker)
|
|
17517
|
+
return false; // No tracker, skip
|
|
17518
|
+
if (tracker.deletedCommentIds.has(task.commentId))
|
|
17519
|
+
return false; // Deduplication
|
|
17520
|
+
tracker.deletedCommentIds.add(task.commentId);
|
|
17521
|
+
return true;
|
|
17522
|
+
}
|
|
17523
|
+
computeCommentCount(postId) {
|
|
17524
|
+
const tracker = this.commentChangeTracker.get(postId);
|
|
17525
|
+
if (!tracker)
|
|
17526
|
+
return 0;
|
|
17527
|
+
const count = tracker.serverCommentCount + tracker.createdCommentIds.size - tracker.deletedCommentIds.size;
|
|
17528
|
+
return Math.max(0, count);
|
|
17529
|
+
}
|
|
17530
|
+
static publishUpdate(postId, newCount) {
|
|
17531
|
+
var _a;
|
|
17532
|
+
const queryKey = ['post', 'get', postId];
|
|
17533
|
+
mergeInCache(queryKey, {
|
|
17534
|
+
localCommentCount: newCount,
|
|
17535
|
+
});
|
|
17536
|
+
const postPayload = (_a = pullFromCache(queryKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
17537
|
+
if (!postPayload)
|
|
17538
|
+
return;
|
|
17539
|
+
fireEvent('local.post.updated', {
|
|
17540
|
+
posts: [postPayload],
|
|
17541
|
+
});
|
|
17542
|
+
}
|
|
17543
|
+
}
|
|
17544
|
+
PostCommentCountEngine.BATCH_SIZE = 50;
|
|
17545
|
+
let instance;
|
|
17546
|
+
var PostCommentCountEngine$1 = {
|
|
17547
|
+
getInstance: () => {
|
|
17548
|
+
if (!instance) {
|
|
17549
|
+
instance = new PostCommentCountEngine();
|
|
17550
|
+
}
|
|
17551
|
+
return instance;
|
|
17552
|
+
},
|
|
17553
|
+
};
|
|
17554
|
+
|
|
17555
|
+
const updateStreamReferences = (streams, streamId, postId) => {
|
|
17556
|
+
if (!streamId)
|
|
17557
|
+
return streams;
|
|
17558
|
+
return streams.map(stream => stream.streamId === streamId
|
|
17559
|
+
? Object.assign(Object.assign({}, stream), { referenceType: 'post', referenceId: postId, postId }) : stream);
|
|
17560
|
+
};
|
|
17561
|
+
const preparePostPayload = (payload) => {
|
|
17562
|
+
const { posts: postsData, postChildren, videoStreamings } = payload, postPayload = __rest(payload, ["posts", "postChildren", "videoStreamings"]);
|
|
17563
|
+
// Unpack community payload by mapping payload field to postSetting value.
|
|
17564
|
+
const communitiesWithPostSetting = addPostSetting({ communities: postPayload.communities });
|
|
17565
|
+
// map users with community
|
|
17566
|
+
const mappedCommunityUsers = postPayload.communityUsers.map(communityUser => {
|
|
17567
|
+
const user = postPayload.users.find(user => user.userId === communityUser.userId);
|
|
17568
|
+
return Object.assign(Object.assign({}, communityUser), { user });
|
|
17569
|
+
});
|
|
17570
|
+
const communityWithMembershipStatus = updateMembershipStatus(communitiesWithPostSetting, mappedCommunityUsers);
|
|
17571
|
+
let mappedNewStream = [];
|
|
17124
17572
|
// feed type
|
|
17125
17573
|
const posts = postsData.map(post => {
|
|
17126
|
-
var _a, _b;
|
|
17574
|
+
var _a, _b, _c, _d;
|
|
17127
17575
|
const feedType = (_a = postPayload.feeds.find(feed => feed.feedId === post.feedId)) === null || _a === void 0 ? void 0 : _a.feedType;
|
|
17128
17576
|
const childPosts = payload.postChildren.filter(children => children.parentPostId === post.postId);
|
|
17129
17577
|
if (childPosts.length > 0 && isAmityLivestreamPost(childPosts[0])) {
|
|
17130
17578
|
mappedNewStream = updateStreamReferences(videoStreamings, (_b = childPosts[0].data) === null || _b === void 0 ? void 0 : _b.streamId, post.postId);
|
|
17131
17579
|
}
|
|
17580
|
+
// --- Computed Comment Count: ResetTask integration ---
|
|
17581
|
+
// Find all comments for this post (referenceType === 'post' && referenceId === postId)
|
|
17582
|
+
const allComments = (payload.comments || []).filter((c) => c.referenceType === 'post' && c.referenceId === post.postId);
|
|
17583
|
+
// Compute latestCreatedAt
|
|
17584
|
+
const latestCreatedAt = allComments.length === 0
|
|
17585
|
+
? new Date().toISOString()
|
|
17586
|
+
: allComments
|
|
17587
|
+
.map(c => c.createdAt)
|
|
17588
|
+
.sort()
|
|
17589
|
+
.at(-1);
|
|
17590
|
+
// Queue ResetTask for this post
|
|
17591
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new ResetTask(post.postId, latestCreatedAt, (_c = post.commentsCount) !== null && _c !== void 0 ? _c : 0));
|
|
17132
17592
|
return Object.assign(Object.assign({}, post), { childPosts,
|
|
17133
|
-
feedType });
|
|
17593
|
+
feedType, localCommentCount: (_d = post.localCommentCount) !== null && _d !== void 0 ? _d : post.commentsCount });
|
|
17134
17594
|
});
|
|
17135
17595
|
return Object.assign(Object.assign({}, postPayload), { postChildren, videoStreamings: mappedNewStream, posts, communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
17136
17596
|
};
|
|
@@ -17232,14 +17692,12 @@ const createLocalPostEventSubscriber = (event, callback) => {
|
|
|
17232
17692
|
callback(payload.posts[0]);
|
|
17233
17693
|
}
|
|
17234
17694
|
else {
|
|
17235
|
-
const
|
|
17236
|
-
const { communities } = data;
|
|
17237
|
-
ingestInCache(data);
|
|
17695
|
+
const { communities } = payload;
|
|
17238
17696
|
if ((communities === null || communities === void 0 ? void 0 : communities[0]) && !['local.post.updated'].includes(event)) {
|
|
17239
17697
|
fireEvent('community.updated', {
|
|
17240
17698
|
communities,
|
|
17241
17699
|
categories: [],
|
|
17242
|
-
communityUsers:
|
|
17700
|
+
communityUsers: payload.communityUsers,
|
|
17243
17701
|
feeds: [],
|
|
17244
17702
|
files: [],
|
|
17245
17703
|
users: [],
|
|
@@ -17510,7 +17968,7 @@ const createCommentEventSubscriber = (event, callback) => {
|
|
|
17510
17968
|
const createLocalCommentEventSubscriber = (event, callback) => {
|
|
17511
17969
|
const client = getActiveClient();
|
|
17512
17970
|
const filter = (payload) => {
|
|
17513
|
-
var _a, _b;
|
|
17971
|
+
var _a, _b, _c, _d, _e;
|
|
17514
17972
|
if (!client.cache) {
|
|
17515
17973
|
// TODO: here we are missing specific properties here!
|
|
17516
17974
|
callback(LinkedObject.comment(payload.comments[0]));
|
|
@@ -17550,7 +18008,13 @@ const createLocalCommentEventSubscriber = (event, callback) => {
|
|
|
17550
18008
|
}
|
|
17551
18009
|
}
|
|
17552
18010
|
}
|
|
17553
|
-
|
|
18011
|
+
else {
|
|
18012
|
+
const postCacheKey = ['post', 'get', comments[0].referenceId];
|
|
18013
|
+
const postCache = (_a = pullFromCache(postCacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
18014
|
+
postCache === null || postCache === void 0 ? void 0 : postCache.comments.push((_b = comments[0]) === null || _b === void 0 ? void 0 : _b.commentId);
|
|
18015
|
+
pushToCache(postCacheKey, postCache);
|
|
18016
|
+
}
|
|
18017
|
+
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; });
|
|
17554
18018
|
queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
|
|
17555
18019
|
}
|
|
17556
18020
|
if (['local.comment.deleted'].includes(event)) {
|
|
@@ -17582,7 +18046,13 @@ const createLocalCommentEventSubscriber = (event, callback) => {
|
|
|
17582
18046
|
}
|
|
17583
18047
|
}
|
|
17584
18048
|
}
|
|
17585
|
-
|
|
18049
|
+
else {
|
|
18050
|
+
const postCacheKey = ['post', 'get', comments[0].referenceId];
|
|
18051
|
+
const postCache = (_d = pullFromCache(postCacheKey)) === null || _d === void 0 ? void 0 : _d.data;
|
|
18052
|
+
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); }) });
|
|
18053
|
+
pushToCache(postCacheKey, updatedPost);
|
|
18054
|
+
}
|
|
18055
|
+
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; });
|
|
17586
18056
|
queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
|
|
17587
18057
|
}
|
|
17588
18058
|
callback(LinkedObject.comment(comment.data));
|
|
@@ -25292,7 +25762,6 @@ getCommentByIds.locally = (commentIds) => {
|
|
|
25292
25762
|
* @async
|
|
25293
25763
|
*/
|
|
25294
25764
|
const createComment = async (bundle) => {
|
|
25295
|
-
var _a;
|
|
25296
25765
|
const client = getActiveClient();
|
|
25297
25766
|
client.log('comment/createComment', bundle);
|
|
25298
25767
|
const { data } = await client.http.post('/api/v3/comments', bundle);
|
|
@@ -25304,22 +25773,7 @@ const createComment = async (bundle) => {
|
|
|
25304
25773
|
if (client.cache)
|
|
25305
25774
|
ingestInCache(data, { cachedAt });
|
|
25306
25775
|
if (['post', 'content'].includes(bundle.referenceType)) {
|
|
25307
|
-
|
|
25308
|
-
if (post) {
|
|
25309
|
-
post.commentsCount += 1;
|
|
25310
|
-
fireEvent('local.post.updated', {
|
|
25311
|
-
posts: [post],
|
|
25312
|
-
categories: [],
|
|
25313
|
-
comments: [],
|
|
25314
|
-
communities: [],
|
|
25315
|
-
communityUsers: data.communityUsers,
|
|
25316
|
-
feeds: [],
|
|
25317
|
-
files: data.files,
|
|
25318
|
-
postChildren: [],
|
|
25319
|
-
users: data.users,
|
|
25320
|
-
videoStreamings: [],
|
|
25321
|
-
});
|
|
25322
|
-
}
|
|
25776
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new CreateTask(bundle.referenceId, comments[0].commentId, data.comments[0].createdAt));
|
|
25323
25777
|
}
|
|
25324
25778
|
else if (bundle.referenceType === 'story') {
|
|
25325
25779
|
const storyIndex = pullFromCache([
|
|
@@ -25478,7 +25932,7 @@ getStoryByStoryId$1.locally = (storyId) => {
|
|
|
25478
25932
|
* @async
|
|
25479
25933
|
*/
|
|
25480
25934
|
const deleteComment = async (commentId, permanent = false) => {
|
|
25481
|
-
var _a;
|
|
25935
|
+
var _a, _b;
|
|
25482
25936
|
const client = getActiveClient();
|
|
25483
25937
|
const comment = await getComment$2(commentId);
|
|
25484
25938
|
// API-FIX: This endpoint has not been implemented yet.
|
|
@@ -25511,26 +25965,14 @@ const deleteComment = async (commentId, permanent = false) => {
|
|
|
25511
25965
|
else {
|
|
25512
25966
|
const post = (_a = pullFromCache(['post', 'get', comment.data.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
25513
25967
|
if (post) {
|
|
25514
|
-
|
|
25515
|
-
|
|
25516
|
-
|
|
25517
|
-
|
|
25968
|
+
const engine = PostCommentCountEngine$1.getInstance();
|
|
25969
|
+
engine.queueCommentChangeTask(new DeleteTask(post.postId, commentId));
|
|
25970
|
+
if (!deleted.parentId && ((_b = deleted.children) === null || _b === void 0 ? void 0 : _b.length) > 0) {
|
|
25971
|
+
// NOTE: delete the parent comment will also remove all children comments
|
|
25972
|
+
deleted.children.forEach((childCommentId) => {
|
|
25973
|
+
engine.queueCommentChangeTask(new DeleteTask(post.postId, childCommentId));
|
|
25974
|
+
});
|
|
25518
25975
|
}
|
|
25519
|
-
else
|
|
25520
|
-
removeCount = 1;
|
|
25521
|
-
post.commentsCount -= removeCount;
|
|
25522
|
-
fireEvent('local.post.updated', {
|
|
25523
|
-
posts: [post],
|
|
25524
|
-
categories: [],
|
|
25525
|
-
comments: [],
|
|
25526
|
-
communities: [],
|
|
25527
|
-
communityUsers: [],
|
|
25528
|
-
feeds: [],
|
|
25529
|
-
files: [],
|
|
25530
|
-
postChildren: [],
|
|
25531
|
-
users: [],
|
|
25532
|
-
videoStreamings: [],
|
|
25533
|
-
});
|
|
25534
25976
|
}
|
|
25535
25977
|
}
|
|
25536
25978
|
fireEvent('local.comment.deleted', {
|
|
@@ -26096,47 +26538,6 @@ var index$d = /*#__PURE__*/Object.freeze({
|
|
|
26096
26538
|
getComments: getComments
|
|
26097
26539
|
});
|
|
26098
26540
|
|
|
26099
|
-
const getPost$1 = async (postId) => {
|
|
26100
|
-
const client = getActiveClient();
|
|
26101
|
-
client.log('post/getPost', postId);
|
|
26102
|
-
isInTombstone('post', postId);
|
|
26103
|
-
let payload;
|
|
26104
|
-
try {
|
|
26105
|
-
// API-FIX: endpoint should not be /list, parameters should be querystring.
|
|
26106
|
-
const response = await client.http.get(`/api/v3/posts/${encodeURIComponent(postId)}`);
|
|
26107
|
-
payload = response.data;
|
|
26108
|
-
}
|
|
26109
|
-
catch (error) {
|
|
26110
|
-
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
26111
|
-
pushToTombstone('post', postId);
|
|
26112
|
-
}
|
|
26113
|
-
throw error;
|
|
26114
|
-
}
|
|
26115
|
-
const data = prepareMembershipPayload(payload, 'communityUsers');
|
|
26116
|
-
const cachedAt = client.cache && Date.now();
|
|
26117
|
-
if (client.cache)
|
|
26118
|
-
ingestInCache(data, { cachedAt });
|
|
26119
|
-
const { posts } = data;
|
|
26120
|
-
const result = posts.find(post => post.postId === postId);
|
|
26121
|
-
return {
|
|
26122
|
-
data: result,
|
|
26123
|
-
cachedAt,
|
|
26124
|
-
};
|
|
26125
|
-
};
|
|
26126
|
-
getPost$1.locally = (postId) => {
|
|
26127
|
-
const client = getActiveClient();
|
|
26128
|
-
client.log('post/getPost.locally', postId);
|
|
26129
|
-
if (!client.cache)
|
|
26130
|
-
return;
|
|
26131
|
-
const cached = pullFromCache(['post', 'get', postId]);
|
|
26132
|
-
if (!cached)
|
|
26133
|
-
return;
|
|
26134
|
-
return {
|
|
26135
|
-
data: cached.data,
|
|
26136
|
-
cachedAt: cached.cachedAt,
|
|
26137
|
-
};
|
|
26138
|
-
};
|
|
26139
|
-
|
|
26140
26541
|
/**
|
|
26141
26542
|
* ```js
|
|
26142
26543
|
* import { onLocalPostDeleted } from '@amityco/ts-sdk-react-native'
|
|
@@ -26235,7 +26636,6 @@ const commentEventHandler$1 = (callback, eventHandler, cacheKey) => {
|
|
|
26235
26636
|
const currentCollection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
26236
26637
|
if (!currentCollection || !currentCollection.data.includes(comment.referenceId))
|
|
26237
26638
|
return;
|
|
26238
|
-
await getPost$1(comment.referenceId);
|
|
26239
26639
|
callback(comment);
|
|
26240
26640
|
});
|
|
26241
26641
|
};
|
|
@@ -26243,12 +26643,8 @@ const generateCommentSubscriptions$1 = (cacheKey) => {
|
|
|
26243
26643
|
const eventHandlers = [
|
|
26244
26644
|
onCommentCreated,
|
|
26245
26645
|
onCommentDeleted,
|
|
26246
|
-
onCommentReactionAdded,
|
|
26247
|
-
onCommentReactionRemoved,
|
|
26248
26646
|
onCommentCreatedLocal,
|
|
26249
26647
|
onCommentDeleteLocal,
|
|
26250
|
-
onLocalCommentReactionAdded,
|
|
26251
|
-
onLocalCommentReactionRemoved,
|
|
26252
26648
|
];
|
|
26253
26649
|
return eventHandlers.map(handler => ({
|
|
26254
26650
|
fn: convertEventPayload((callback) => commentEventHandler$1(callback, handler, cacheKey), 'referenceId', 'post'),
|
|
@@ -26612,6 +27008,47 @@ class UserFeedQueryStreamController extends QueryStreamController {
|
|
|
26612
27008
|
}
|
|
26613
27009
|
}
|
|
26614
27010
|
|
|
27011
|
+
const getPost$1 = async (postId) => {
|
|
27012
|
+
const client = getActiveClient();
|
|
27013
|
+
client.log('post/getPost', postId);
|
|
27014
|
+
isInTombstone('post', postId);
|
|
27015
|
+
let payload;
|
|
27016
|
+
try {
|
|
27017
|
+
// API-FIX: endpoint should not be /list, parameters should be querystring.
|
|
27018
|
+
const response = await client.http.get(`/api/v3/posts/${encodeURIComponent(postId)}`);
|
|
27019
|
+
payload = response.data;
|
|
27020
|
+
}
|
|
27021
|
+
catch (error) {
|
|
27022
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
27023
|
+
pushToTombstone('post', postId);
|
|
27024
|
+
}
|
|
27025
|
+
throw error;
|
|
27026
|
+
}
|
|
27027
|
+
const data = prepareMembershipPayload(payload, 'communityUsers');
|
|
27028
|
+
const cachedAt = client.cache && Date.now();
|
|
27029
|
+
if (client.cache)
|
|
27030
|
+
ingestInCache(data, { cachedAt });
|
|
27031
|
+
const { posts } = data;
|
|
27032
|
+
const result = posts.find(post => post.postId === postId);
|
|
27033
|
+
return {
|
|
27034
|
+
data: result,
|
|
27035
|
+
cachedAt,
|
|
27036
|
+
};
|
|
27037
|
+
};
|
|
27038
|
+
getPost$1.locally = (postId) => {
|
|
27039
|
+
const client = getActiveClient();
|
|
27040
|
+
client.log('post/getPost.locally', postId);
|
|
27041
|
+
if (!client.cache)
|
|
27042
|
+
return;
|
|
27043
|
+
const cached = pullFromCache(['post', 'get', postId]);
|
|
27044
|
+
if (!cached)
|
|
27045
|
+
return;
|
|
27046
|
+
return {
|
|
27047
|
+
data: cached.data,
|
|
27048
|
+
cachedAt: cached.cachedAt,
|
|
27049
|
+
};
|
|
27050
|
+
};
|
|
27051
|
+
|
|
26615
27052
|
class UserFeedLiveCollectionController extends LiveCollectionController {
|
|
26616
27053
|
constructor(query, callback) {
|
|
26617
27054
|
const queryStreamId = hash__default["default"](query);
|
|
@@ -26745,12 +27182,240 @@ const getUserFeed = (params, callback, config) => {
|
|
|
26745
27182
|
};
|
|
26746
27183
|
/* end_public_function */
|
|
26747
27184
|
|
|
27185
|
+
class CommunityFeedPaginationController extends PaginationController {
|
|
27186
|
+
async getRequest(queryParams, token) {
|
|
27187
|
+
const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, includeDeleted, communityId } = queryParams, params = __rest(queryParams, ["limit", "includeDeleted", "communityId"]);
|
|
27188
|
+
const options = token ? { token } : { limit };
|
|
27189
|
+
const { data: queryResponse } = await this.http.get(`/api/v5/posts`, {
|
|
27190
|
+
params: Object.assign(Object.assign({}, params), { targetId: communityId, targetType: 'community', isDeleted: inferIsDeleted(includeDeleted), matchingOnlyParentPost: true, options }),
|
|
27191
|
+
});
|
|
27192
|
+
return queryResponse;
|
|
27193
|
+
}
|
|
27194
|
+
}
|
|
27195
|
+
|
|
27196
|
+
class CommunityFeedQueryStreamController extends QueryStreamController {
|
|
27197
|
+
constructor(query, cacheKey, notifyChange, preparePayload) {
|
|
27198
|
+
super(query, cacheKey);
|
|
27199
|
+
this.notifyChange = notifyChange;
|
|
27200
|
+
this.preparePayload = preparePayload;
|
|
27201
|
+
}
|
|
27202
|
+
async saveToMainDB(response) {
|
|
27203
|
+
const processedPayload = await this.preparePayload(response);
|
|
27204
|
+
const client = getActiveClient();
|
|
27205
|
+
const cachedAt = client.cache && Date.now();
|
|
27206
|
+
if (client.cache) {
|
|
27207
|
+
ingestInCache(processedPayload, { cachedAt });
|
|
27208
|
+
}
|
|
27209
|
+
}
|
|
27210
|
+
appendToQueryStream(response, direction, refresh = false) {
|
|
27211
|
+
var _a, _b;
|
|
27212
|
+
if (refresh) {
|
|
27213
|
+
pushToCache(this.cacheKey, {
|
|
27214
|
+
data: response.posts.map(getResolver('post')),
|
|
27215
|
+
});
|
|
27216
|
+
}
|
|
27217
|
+
else {
|
|
27218
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27219
|
+
const posts = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
27220
|
+
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...posts, ...response.posts.map(getResolver('post'))])] }));
|
|
27221
|
+
}
|
|
27222
|
+
}
|
|
27223
|
+
reactor(action) {
|
|
27224
|
+
return (post) => {
|
|
27225
|
+
var _a, _b;
|
|
27226
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27227
|
+
if (!collection)
|
|
27228
|
+
return;
|
|
27229
|
+
if (action === EnumPostActions.OnPostDeleted) {
|
|
27230
|
+
collection.data = collection.data.filter(postId => postId !== post.postId);
|
|
27231
|
+
}
|
|
27232
|
+
if (post.parentPostId && post.isDeleted) {
|
|
27233
|
+
const parentPost = (_b = pullFromCache([
|
|
27234
|
+
'post',
|
|
27235
|
+
'get',
|
|
27236
|
+
post.parentPostId,
|
|
27237
|
+
])) === null || _b === void 0 ? void 0 : _b.data;
|
|
27238
|
+
if (!parentPost)
|
|
27239
|
+
return;
|
|
27240
|
+
parentPost.children = parentPost.children.filter(childId => childId !== post.postId);
|
|
27241
|
+
pushToCache(['post', 'get', parentPost.postId], parentPost);
|
|
27242
|
+
}
|
|
27243
|
+
if (action === EnumPostActions.OnPostDeclined) {
|
|
27244
|
+
collection.data = collection.data.filter(postId => postId !== post.postId);
|
|
27245
|
+
}
|
|
27246
|
+
if (action === EnumPostActions.OnPostCreated || action === EnumPostActions.OnPostApproved) {
|
|
27247
|
+
collection.data = [...new Set([post.postId, ...collection.data])];
|
|
27248
|
+
}
|
|
27249
|
+
pushToCache(this.cacheKey, collection);
|
|
27250
|
+
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
27251
|
+
};
|
|
27252
|
+
}
|
|
27253
|
+
subscribeRTE(createSubscriber) {
|
|
27254
|
+
return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
|
|
27255
|
+
}
|
|
27256
|
+
}
|
|
27257
|
+
|
|
27258
|
+
const commentEventHandler = (callback, eventHandler, cacheKey, resolveId) => {
|
|
27259
|
+
return eventHandler(async (comment) => {
|
|
27260
|
+
var _a;
|
|
27261
|
+
const currentCollection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27262
|
+
if (!currentCollection ||
|
|
27263
|
+
!currentCollection.data.includes(resolveId ? resolveId(comment.referenceId) : comment.referenceId))
|
|
27264
|
+
return;
|
|
27265
|
+
callback(comment);
|
|
27266
|
+
});
|
|
27267
|
+
};
|
|
27268
|
+
const generateCommentSubscriptions = ({ cacheKey, resolveId, }) => {
|
|
27269
|
+
const eventHandlers = [
|
|
27270
|
+
onCommentCreated,
|
|
27271
|
+
onCommentDeleted,
|
|
27272
|
+
onCommentCreatedLocal,
|
|
27273
|
+
onCommentDeleteLocal,
|
|
27274
|
+
];
|
|
27275
|
+
return eventHandlers.map(handler => ({
|
|
27276
|
+
fn: convertEventPayload((callback) => commentEventHandler(callback, handler, cacheKey, resolveId), 'referenceId', 'post'),
|
|
27277
|
+
action: EnumPostActions.OnPostUpdated,
|
|
27278
|
+
}));
|
|
27279
|
+
};
|
|
27280
|
+
const getPostSubscription = (cacheKey) => {
|
|
27281
|
+
return [
|
|
27282
|
+
{ fn: onPostCreated, action: EnumPostActions.OnPostCreated },
|
|
27283
|
+
{ fn: onPostUpdated, action: EnumPostActions.OnPostUpdated },
|
|
27284
|
+
{ fn: onPostUpdatedLocal, action: EnumPostActions.OnPostUpdated },
|
|
27285
|
+
{ fn: onPostDeleted, action: EnumPostActions.OnPostDeleted },
|
|
27286
|
+
{ fn: onPostFlagged, action: EnumPostActions.OnPostFlagged },
|
|
27287
|
+
{ fn: onPostUnflagged, action: EnumPostActions.OnPostUnflagged },
|
|
27288
|
+
{ fn: onPostApproved, action: EnumPostActions.OnPostApproved },
|
|
27289
|
+
{ fn: onPostDeclined, action: EnumPostActions.OnPostDeclined },
|
|
27290
|
+
{ fn: onPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
|
|
27291
|
+
{ fn: onPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
|
|
27292
|
+
{ fn: onLocalPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
|
|
27293
|
+
{ fn: onLocalPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
|
|
27294
|
+
{ fn: onLocalPostDeleted, action: EnumPostActions.OnPostDeleted },
|
|
27295
|
+
...generateCommentSubscriptions({ cacheKey }),
|
|
27296
|
+
];
|
|
27297
|
+
};
|
|
27298
|
+
const resolvePostIdsFromRooms = (rooms, posts) => {
|
|
27299
|
+
var _a;
|
|
27300
|
+
return ((_a = rooms
|
|
27301
|
+
.map(room => {
|
|
27302
|
+
const post = posts.find(post => post.postId === room.referenceId);
|
|
27303
|
+
return post ? getResolver('post')({ postId: post === null || post === void 0 ? void 0 : post.postId }) : undefined;
|
|
27304
|
+
})
|
|
27305
|
+
.filter(isNonNullable)) !== null && _a !== void 0 ? _a : []);
|
|
27306
|
+
};
|
|
27307
|
+
|
|
27308
|
+
class CommunityFeedLiveCollectionController extends LiveCollectionController {
|
|
27309
|
+
constructor(query, callback) {
|
|
27310
|
+
const queryStreamId = hash__default["default"](query);
|
|
27311
|
+
const cacheKey = ['communityFeed', 'collection', queryStreamId];
|
|
27312
|
+
const paginationController = new CommunityFeedPaginationController(query);
|
|
27313
|
+
super(paginationController, queryStreamId, cacheKey, callback);
|
|
27314
|
+
this.query = query;
|
|
27315
|
+
this.queryStreamController = new CommunityFeedQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), preparePostPayload);
|
|
27316
|
+
this.callback = callback.bind(this);
|
|
27317
|
+
this.loadPage({ initial: true });
|
|
27318
|
+
}
|
|
27319
|
+
setup() {
|
|
27320
|
+
var _a;
|
|
27321
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27322
|
+
if (!collection) {
|
|
27323
|
+
pushToCache(this.cacheKey, {
|
|
27324
|
+
data: [],
|
|
27325
|
+
params: {},
|
|
27326
|
+
});
|
|
27327
|
+
}
|
|
27328
|
+
}
|
|
27329
|
+
async persistModel(queryPayload) {
|
|
27330
|
+
await this.queryStreamController.saveToMainDB(queryPayload);
|
|
27331
|
+
}
|
|
27332
|
+
persistQueryStream({ response, direction, refresh, }) {
|
|
27333
|
+
this.queryStreamController.appendToQueryStream(response, direction, refresh);
|
|
27334
|
+
}
|
|
27335
|
+
startSubscription() {
|
|
27336
|
+
return this.queryStreamController.subscribeRTE(getPostSubscription(this.cacheKey));
|
|
27337
|
+
}
|
|
27338
|
+
notifyChange({ origin, loading, error }) {
|
|
27339
|
+
var _a, _b;
|
|
27340
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27341
|
+
if (!collection)
|
|
27342
|
+
return;
|
|
27343
|
+
const data = ((_b = collection.data
|
|
27344
|
+
.map(id => pullFromCache(['post', 'get', id]))
|
|
27345
|
+
.filter(isNonNullable)
|
|
27346
|
+
.map(({ data }) => data)) !== null && _b !== void 0 ? _b : []).map(LinkedObject.post);
|
|
27347
|
+
if (!this.shouldNotify(data) && origin === 'event')
|
|
27348
|
+
return;
|
|
27349
|
+
this.callback({
|
|
27350
|
+
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
27351
|
+
data,
|
|
27352
|
+
hasNextPage: !!this.paginationController.getNextToken(),
|
|
27353
|
+
loading,
|
|
27354
|
+
error,
|
|
27355
|
+
});
|
|
27356
|
+
}
|
|
27357
|
+
}
|
|
27358
|
+
|
|
27359
|
+
/* begin_public_function
|
|
27360
|
+
id: feed.query.community_feed
|
|
27361
|
+
*/
|
|
27362
|
+
/**
|
|
27363
|
+
* ```js
|
|
27364
|
+
* import { FeedRepository } from '@amityco/ts-sdk'
|
|
27365
|
+
*
|
|
27366
|
+
* let posts = []
|
|
27367
|
+
* const unsubscribe = FeedRepository.getCommunityFeed({
|
|
27368
|
+
* communityId: 'community-id',
|
|
27369
|
+
* sortBy?: 'lastCreated' | 'firstCreated' | 'lastUpdated' | 'firstUpdated',
|
|
27370
|
+
* includeDeleted?: boolean,
|
|
27371
|
+
* feedType?: 'reviewing' | 'published' | 'declined',
|
|
27372
|
+
* tags?: string[],
|
|
27373
|
+
* includeMixedStructure?: boolean,
|
|
27374
|
+
* limit?: number,
|
|
27375
|
+
* }, response => processResponse(response))
|
|
27376
|
+
* ```
|
|
27377
|
+
*
|
|
27378
|
+
* Observe all mutations on a list of {@link Amity.Post} for a given community feed.
|
|
27379
|
+
*
|
|
27380
|
+
* @param params - Parameters for querying the community feed:
|
|
27381
|
+
* @param params.communityId The ID of the community (required)
|
|
27382
|
+
* @param params.sortBy The sorting order of the feed (optional)
|
|
27383
|
+
* @param params.includeDeleted Whether to include deleted posts (optional)
|
|
27384
|
+
* @param params.feedType The type of the feed: 'reviewing', 'published', or 'declined' (optional)
|
|
27385
|
+
* @param params.tags Array of tags to filter posts (optional)
|
|
27386
|
+
* @param params.includeMixedStructure Whether to include mixed structure posts (optional)
|
|
27387
|
+
* @param params.limit The maximum number of posts to retrieve (optional)
|
|
27388
|
+
* @param callback The function to call when new data are available
|
|
27389
|
+
* @param config Additional live collection configuration (optional)
|
|
27390
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the feed
|
|
27391
|
+
*
|
|
27392
|
+
* @category Posts Live Collection
|
|
27393
|
+
*/
|
|
27394
|
+
const getCommunityFeed = (params, callback, config) => {
|
|
27395
|
+
const { log, cache } = getActiveClient();
|
|
27396
|
+
if (!cache) {
|
|
27397
|
+
console.log(ENABLE_CACHE_MESSAGE);
|
|
27398
|
+
}
|
|
27399
|
+
const timestamp = Date.now();
|
|
27400
|
+
log(`getCommunityFeed(tmpid: ${timestamp}) > listen`);
|
|
27401
|
+
const communityFeedLiveCollection = new CommunityFeedLiveCollectionController(params, callback);
|
|
27402
|
+
const disposers = communityFeedLiveCollection.startSubscription();
|
|
27403
|
+
const cacheKey = communityFeedLiveCollection.getCacheKey();
|
|
27404
|
+
disposers.push(() => dropFromCache(cacheKey));
|
|
27405
|
+
return () => {
|
|
27406
|
+
log(`getCommunityFeed(tmpid: ${timestamp}) > dispose`);
|
|
27407
|
+
disposers.forEach(fn => fn());
|
|
27408
|
+
};
|
|
27409
|
+
};
|
|
27410
|
+
/* end_public_function */
|
|
27411
|
+
|
|
26748
27412
|
var index$c = /*#__PURE__*/Object.freeze({
|
|
26749
27413
|
__proto__: null,
|
|
26750
27414
|
queryGlobalFeed: queryGlobalFeed,
|
|
26751
27415
|
getCustomRankingGlobalFeed: getCustomRankingGlobalFeed,
|
|
26752
27416
|
getGlobalFeed: getGlobalFeed,
|
|
26753
|
-
getUserFeed: getUserFeed
|
|
27417
|
+
getUserFeed: getUserFeed,
|
|
27418
|
+
getCommunityFeed: getCommunityFeed
|
|
26754
27419
|
});
|
|
26755
27420
|
|
|
26756
27421
|
/* begin_public_function
|
|
@@ -27496,61 +28161,6 @@ class PostQueryStreamController extends QueryStreamController {
|
|
|
27496
28161
|
}
|
|
27497
28162
|
}
|
|
27498
28163
|
|
|
27499
|
-
const commentEventHandler = (callback, eventHandler, cacheKey, resolveId) => {
|
|
27500
|
-
return eventHandler(async (comment) => {
|
|
27501
|
-
var _a;
|
|
27502
|
-
const currentCollection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27503
|
-
if (!currentCollection ||
|
|
27504
|
-
!currentCollection.data.includes(resolveId ? resolveId(comment.referenceId) : comment.referenceId))
|
|
27505
|
-
return;
|
|
27506
|
-
await getPost$1(comment.referenceId);
|
|
27507
|
-
callback(comment);
|
|
27508
|
-
});
|
|
27509
|
-
};
|
|
27510
|
-
const generateCommentSubscriptions = ({ cacheKey, resolveId, }) => {
|
|
27511
|
-
const eventHandlers = [
|
|
27512
|
-
onCommentCreated,
|
|
27513
|
-
onCommentDeleted,
|
|
27514
|
-
onCommentReactionAdded,
|
|
27515
|
-
onCommentReactionRemoved,
|
|
27516
|
-
onCommentCreatedLocal,
|
|
27517
|
-
onCommentDeleteLocal,
|
|
27518
|
-
onLocalCommentReactionAdded,
|
|
27519
|
-
onLocalCommentReactionRemoved,
|
|
27520
|
-
];
|
|
27521
|
-
return eventHandlers.map(handler => ({
|
|
27522
|
-
fn: convertEventPayload((callback) => commentEventHandler(callback, handler, cacheKey, resolveId), 'referenceId', 'post'),
|
|
27523
|
-
action: EnumPostActions.OnPostUpdated,
|
|
27524
|
-
}));
|
|
27525
|
-
};
|
|
27526
|
-
const getPostSubscription = (cacheKey) => {
|
|
27527
|
-
return [
|
|
27528
|
-
{ fn: onPostCreated, action: EnumPostActions.OnPostCreated },
|
|
27529
|
-
{ fn: onPostUpdated, action: EnumPostActions.OnPostUpdated },
|
|
27530
|
-
{ fn: onPostUpdatedLocal, action: EnumPostActions.OnPostUpdated },
|
|
27531
|
-
{ fn: onPostDeleted, action: EnumPostActions.OnPostDeleted },
|
|
27532
|
-
{ fn: onPostFlagged, action: EnumPostActions.OnPostFlagged },
|
|
27533
|
-
{ fn: onPostUnflagged, action: EnumPostActions.OnPostUnflagged },
|
|
27534
|
-
{ fn: onPostApproved, action: EnumPostActions.OnPostApproved },
|
|
27535
|
-
{ fn: onPostDeclined, action: EnumPostActions.OnPostDeclined },
|
|
27536
|
-
{ fn: onPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
|
|
27537
|
-
{ fn: onPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
|
|
27538
|
-
{ fn: onLocalPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
|
|
27539
|
-
{ fn: onLocalPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
|
|
27540
|
-
{ fn: onLocalPostDeleted, action: EnumPostActions.OnPostDeleted },
|
|
27541
|
-
...generateCommentSubscriptions({ cacheKey }),
|
|
27542
|
-
];
|
|
27543
|
-
};
|
|
27544
|
-
const resolvePostIdsFromRooms = (rooms, posts) => {
|
|
27545
|
-
var _a;
|
|
27546
|
-
return ((_a = rooms
|
|
27547
|
-
.map(room => {
|
|
27548
|
-
const post = posts.find(post => post.postId === room.referenceId);
|
|
27549
|
-
return post ? getResolver('post')({ postId: post === null || post === void 0 ? void 0 : post.postId }) : undefined;
|
|
27550
|
-
})
|
|
27551
|
-
.filter(isNonNullable)) !== null && _a !== void 0 ? _a : []);
|
|
27552
|
-
};
|
|
27553
|
-
|
|
27554
28164
|
class PostLiveCollectionController extends LiveCollectionController {
|
|
27555
28165
|
constructor(query, callback) {
|
|
27556
28166
|
const queryStreamId = hash__default["default"](query);
|