@amityco/ts-sdk-react-native 7.5.3-2c40726.0 → 7.5.3

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/index.esm.js CHANGED
@@ -101,8 +101,8 @@ const PostContentType = Object.freeze({
101
101
 
102
102
  function getVersion() {
103
103
  try {
104
- // the string ''v7.5.2-esm'' should be replaced by actual value by @rollup/plugin-replace
105
- return 'v7.5.2-esm';
104
+ // the string ''v7.5.3-esm'' should be replaced by actual value by @rollup/plugin-replace
105
+ return 'v7.5.3-esm';
106
106
  }
107
107
  catch (error) {
108
108
  return '__dev__';
@@ -24800,6 +24800,266 @@ const removeChannelMarkerCache = (channel) => {
24800
24800
  dropFromCache(['channelMarker', 'get', id], true);
24801
24801
  };
24802
24802
 
24803
+ /* eslint-disable no-param-reassign */
24804
+ /*
24805
+ * declared earlier to accomodate case when logging in with a different user
24806
+ * than the one already connected, in which case the existing subscriptions need
24807
+ * to be cleared
24808
+ */
24809
+ let subscriptions = [];
24810
+ async function runMqtt() {
24811
+ await modifyMqttConnection();
24812
+ }
24813
+ /* begin_public_function
24814
+ id: client.login
24815
+ */
24816
+ /**
24817
+ * ```js
24818
+ * import { login } from '@amityco/ts-sdk-react-native/client/api'
24819
+ * const success = await login({
24820
+ * userId: 'XYZ123456789',
24821
+ * })
24822
+ * ```
24823
+ *
24824
+ * Connects an {@link Amity.Client} instance to ASC servers
24825
+ *
24826
+ * @param params the connect parameters
24827
+ * @param params.userId the user ID for the current session
24828
+ * @param params.displayName the user's displayName for the current session
24829
+ * @param params.deviceId Manual override of the user's device id (for device management)
24830
+ * @param params.authToken The authentication token - necessary when network option is set to secure
24831
+ * @returns a success boolean if connected
24832
+ *
24833
+ * @category Client API
24834
+ * @async
24835
+ */
24836
+ const login = async (params, sessionHandler, config) => {
24837
+ var _a;
24838
+ const client = getActiveClient();
24839
+ let unsubWatcher;
24840
+ client.log('client/api/connectClient', Object.assign({ apiKey: client.apiKey, sessionState: client.sessionState }, params));
24841
+ // if connecting to a different userId than the one that is connected currently
24842
+ if (client.userId && client.userId !== params.userId) {
24843
+ await logout();
24844
+ // Remove subscription to ban and delete
24845
+ subscriptions.forEach(fn => fn());
24846
+ subscriptions = [];
24847
+ }
24848
+ // default values
24849
+ const defaultDeviceId = await getDeviceId();
24850
+ try {
24851
+ const { users } = await setClientToken({
24852
+ params: Object.assign(Object.assign({}, params), { displayName: params === null || params === void 0 ? void 0 : params.displayName, deviceId: (params === null || params === void 0 ? void 0 : params.deviceId) || defaultDeviceId }),
24853
+ options: {
24854
+ setAccessTokenCookie: true,
24855
+ },
24856
+ });
24857
+ const user = users.find(u => u.userId === params.userId);
24858
+ if (user == null) {
24859
+ throw new ASCError(`${params.userId} has not been founded`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
24860
+ }
24861
+ if (user.isDeleted) {
24862
+ terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
24863
+ return false;
24864
+ }
24865
+ if (user.isGlobalBanned) {
24866
+ terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
24867
+ return false;
24868
+ }
24869
+ // FIXME: events are duplicated if connectClient is called few times without disconnectClient
24870
+ // wire websocket events to our event emitter
24871
+ proxyWebsocketEvents(client.ws, client.emitter);
24872
+ (_a = client.ws) === null || _a === void 0 ? void 0 : _a.open();
24873
+ client.userId = user.userId;
24874
+ client.sessionHandler = sessionHandler;
24875
+ /*
24876
+ * Cannot push to subscriptions as watcher needs to continue working even if
24877
+ * token expires
24878
+ */
24879
+ unsubWatcher = client.accessTokenExpiryWatcher(sessionHandler);
24880
+ setActiveUser(user);
24881
+ }
24882
+ catch (error) {
24883
+ /*
24884
+ * if getting token failed session state reverts to initial state when app
24885
+ * is first launched
24886
+ */
24887
+ SessionWatcher$1.getInstance().setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
24888
+ // pass error down tree so the calling function handle it
24889
+ throw error;
24890
+ }
24891
+ if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
24892
+ runMqtt();
24893
+ }
24894
+ await initializeMessagePreviewSetting();
24895
+ if (subscriptions.length === 0) {
24896
+ subscriptions.push(
24897
+ // GLOBAL_BAN
24898
+ onClientBanned((_) => {
24899
+ terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
24900
+ subscriptions.forEach(fn => fn());
24901
+ unsubWatcher();
24902
+ }), onTokenTerminated(_ => {
24903
+ terminateClient();
24904
+ subscriptions.forEach(fn => fn());
24905
+ unsubWatcher();
24906
+ }), onUserDeleted$2((user) => {
24907
+ if (user.userId === client.userId) {
24908
+ terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
24909
+ subscriptions.forEach(fn => fn());
24910
+ unsubWatcher();
24911
+ }
24912
+ }), onTokenExpired(state => {
24913
+ SessionWatcher$1.getInstance().setSessionState(state);
24914
+ logout();
24915
+ subscriptions.forEach(fn => fn());
24916
+ }),
24917
+ // NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
24918
+ // the channel because currently backend can't handle this, so every time a user is banned from
24919
+ // a channel or the channel is deleted the channel's unread count will not be reset to zero
24920
+ onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler());
24921
+ if (client.useLegacyUnreadCount) {
24922
+ subscriptions.push(readReceiptSyncEngineOnLoginHandler());
24923
+ }
24924
+ else
24925
+ subscriptions.push(legacyReadReceiptSyncEngineOnLoginHandler());
24926
+ }
24927
+ return true;
24928
+ };
24929
+ /* end_public_function */
24930
+
24931
+ /* begin_public_function
24932
+ id: client.renew_access_token
24933
+ */
24934
+ /*
24935
+ * Renewal defintion accepted by SessionHandler interface
24936
+ *
24937
+ * Tech Spec:
24938
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Session-Handler
24939
+ *
24940
+ * @category private
24941
+ */
24942
+ const renewal = () => {
24943
+ let tokenRenewed = false;
24944
+ let renewTimeoutId;
24945
+ const client = getActiveClient();
24946
+ client.log('initiating access token renewal');
24947
+ /*
24948
+ * Renews a token if it is hasn't been renewed before. Also marks token as
24949
+ * renewed once done
24950
+ * Per instance of Renewal, only one renewal is allowed
24951
+ */
24952
+ const renewToken = async (authToken) => {
24953
+ const { userId, displayName } = getActiveUser();
24954
+ const deviceId = await getDeviceId();
24955
+ const params = { userId, displayName, authToken, deviceId };
24956
+ if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.sessionHandler) {
24957
+ await login(params, client.sessionHandler);
24958
+ }
24959
+ else {
24960
+ // about to expire
24961
+ await setClientToken({
24962
+ params,
24963
+ options: {
24964
+ setAccessTokenCookie: true,
24965
+ },
24966
+ });
24967
+ }
24968
+ tokenRenewed = true;
24969
+ if (renewTimeoutId)
24970
+ clearTimeout(renewTimeoutId);
24971
+ };
24972
+ return {
24973
+ renew: () => {
24974
+ if (tokenRenewed) {
24975
+ console.log("'renew' method can be called only once per renewal instance");
24976
+ return;
24977
+ }
24978
+ renewToken();
24979
+ },
24980
+ renewWithAuthToken: (authToken) => {
24981
+ if (tokenRenewed) {
24982
+ console.log("'renewWithAuthToken' method can be called only once per renewal instance");
24983
+ return;
24984
+ }
24985
+ renewToken(authToken);
24986
+ },
24987
+ unableToRetrieveAuthToken: () => {
24988
+ renewTimeoutId = setTimeout(() => {
24989
+ var _a;
24990
+ (_a = client.sessionHandler) === null || _a === void 0 ? void 0 : _a.sessionWillRenewAccessToken(renewal());
24991
+ }, ACCESS_TOKEN_WATCHER_INTERVAL);
24992
+ },
24993
+ };
24994
+ };
24995
+ /* end_public_function */
24996
+
24997
+ const ABOUT_TO_EXPIRE_THRESHOLD = 80 / 100;
24998
+ const COMPENSATED_DELAY = 5 * MINUTE;
24999
+ /*
25000
+ * a helper function to check if the token has expires
25001
+ *
25002
+ * @param token to be checked
25003
+ * @returns boolean indicating if token expires
25004
+ *
25005
+ * @category private
25006
+ */
25007
+ const isExpired = (expiresAt) => Date.now() > Date.parse(expiresAt) - COMPENSATED_DELAY;
25008
+ /*
25009
+ * a helper function to check if the token is about to expire
25010
+ *
25011
+ * @param token to be checked
25012
+ * @returns boolean indicating if token is aboutToExpire
25013
+ *
25014
+ * @category private
25015
+ */
25016
+ const isAboutToExpire = (params) => {
25017
+ const { expiresAt, issuedAt } = params;
25018
+ const expires = Date.parse(expiresAt);
25019
+ const issued = Date.parse(issuedAt);
25020
+ const now = Date.now();
25021
+ const duration = expires - issued - COMPENSATED_DELAY;
25022
+ const aboutToExpireAt = issued + duration * ABOUT_TO_EXPIRE_THRESHOLD;
25023
+ return now > aboutToExpireAt && now < expires;
25024
+ };
25025
+ /*
25026
+ * Monitors time to expire of token and updates session state to aboutToExpire
25027
+ *
25028
+ * @returns intervalId to be cleared after trigger
25029
+ *
25030
+ * @category private
25031
+ */
25032
+ const accessTokenExpiryWatcher = (sessionHandler) => {
25033
+ const interval = setInterval(() => {
25034
+ const client = getActiveClient();
25035
+ if (!client.token)
25036
+ return;
25037
+ const { issuedAt, expiresAt } = client.token;
25038
+ if (isExpired(expiresAt)) {
25039
+ /*
25040
+ * the event handler will take care of updating session state
25041
+ * Note, this will also clear the interval id, so this event will only be
25042
+ * fired once
25043
+ */
25044
+ fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
25045
+ /*
25046
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Automatically-initiate-renewal-flow
25047
+ *
25048
+ * Why sechduled task?
25049
+ * Since fireEvent is scheduled, it will be called
25050
+ * after sessionHandler leading to an invalid state change from
25051
+ * establishing to tokenExpired
25052
+ */
25053
+ scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
25054
+ return;
25055
+ }
25056
+ if (isAboutToExpire({ expiresAt, issuedAt })) {
25057
+ sessionHandler.sessionWillRenewAccessToken(renewal());
25058
+ }
25059
+ }, ACCESS_TOKEN_WATCHER_INTERVAL);
25060
+ return () => clearInterval(interval);
25061
+ };
25062
+
24803
25063
  const callbacks$9 = [];
24804
25064
  let mainDisposer$8 = null;
24805
25065
  const dispose$9 = (cb) => {
@@ -25072,33 +25332,6 @@ const onChannelMemberRoleRemoved = (callback) => {
25072
25332
  return () => dispose(callback);
25073
25333
  };
25074
25334
 
25075
- /**
25076
- * ```js
25077
- * import { onUserMarkerSync } from '@amityco/ts-sdk-react-native'
25078
- * const dispose = onUserMarkerSync(UserMarker => {
25079
- * // ...
25080
- * })
25081
- * ```
25082
- *
25083
- * Fired when an {@link Amity.UserMarker} has been sync
25084
- *
25085
- * @param callback The function to call when the event was fired
25086
- * @returns an {@link Amity.Unsubscriber} function to stop listening
25087
- *
25088
- * @category UserMarker Events
25089
- */
25090
- const onUserMarkerSync = (callback) => {
25091
- const client = getActiveClient();
25092
- const filter = (payload) => {
25093
- const { userMarkers, userEntityMarkers: userEntityMarkersPayload, userFeedMarkers: userFeedMarkersPayload } = payload, rest = __rest(payload, ["userMarkers", "userEntityMarkers", "userFeedMarkers"]);
25094
- const userEntityMarkers = convertChannelMarkerResponse(userEntityMarkersPayload);
25095
- const userFeedMarker = convertSubChannelMarkerResponse(userFeedMarkersPayload);
25096
- ingestInCache(Object.assign({ userMarkers, userEntityMarkers, userFeedMarker }, rest));
25097
- callback(userMarkers[0]);
25098
- };
25099
- return createEventSubscriber(client, 'UserMarker/onUserMarkerSync', 'marker.user-sync', filter);
25100
- };
25101
-
25102
25335
  /**
25103
25336
  * ```js
25104
25337
  * import { onFeedMarkerUpdated } from '@amityco/ts-sdk-react-native'
@@ -25370,52 +25603,11 @@ const markerSync = async (deviceLastSyncAt) => {
25370
25603
  };
25371
25604
  };
25372
25605
 
25373
- const enableUnreadCount = () => {
25374
- const client = getActiveClient();
25375
- client.log('client/api/isUnreadCountEnabled', client.isUnreadCountEnabled);
25376
- if (!client) {
25377
- throw new ASCError('There is no active client', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
25378
- }
25379
- if (client.isUnreadCountEnabled)
25380
- return false;
25381
- client.isUnreadCountEnabled = true;
25382
- client.useLegacyUnreadCount = false;
25383
- client.emitter.emit('unreadCountEnabled', true);
25384
- return true;
25385
- };
25386
-
25387
- /**
25388
- * ```js
25389
- * import { onFeedMarkerUpdated } from '@amityco/ts-sdk-react-native'
25390
- * const dispose = onFeedMarkerUpdated(feedMarker => {
25391
- * // ...
25392
- * })
25393
- * ```
25394
- *
25395
- * Fired when an {@link Amity.UserFeedMarker} has been updated
25396
- *
25397
- * @param callback The function to call when the event was fired
25398
- * @returns an {@link Amity.Unsubscriber} function to stop listening
25399
- *
25400
- * @category FeedMarker Events
25401
- */
25402
- const onUserFeedMarkerUpdated = (callback) => {
25403
- const client = getActiveClient();
25404
- const filter = (payload) => {
25405
- persistUnreadCountInfo(payload);
25406
- payload.feedMarkers.forEach(feedMarker => {
25407
- callback(feedMarker);
25408
- });
25409
- };
25410
- return createEventSubscriber(client, 'feedMarker/onUserFeedMarkerUpdated', 'marker.userFeed-updated', filter);
25411
- };
25412
-
25413
25606
  const SYNC_TRIGGER_INTERVAL_TIME = 2000;
25414
- const ON_SUB_CHANNEL_DELETE_SYNC_TRIGGER_DELAY = 2000;
25415
25607
  let isSyncRunning = false;
25416
25608
  let disposers$1 = [];
25417
25609
  let isWaitingForResponse = false;
25418
- let isConsistentMode = true;
25610
+ const isConsistentMode = true;
25419
25611
  let deviceLastSyncAt = null;
25420
25612
  const getDeviceLastSyncAt = () => {
25421
25613
  if (deviceLastSyncAt == null) {
@@ -25430,12 +25622,6 @@ const saveDeviceLastSyncAt = (lastSyncAt) => {
25430
25622
  deviceLastSyncAt = lastSyncAt;
25431
25623
  }
25432
25624
  };
25433
- const fetchDeviceLastSyncAt = async () => {
25434
- const { data: userMarker } = await getUserMarker();
25435
- if (userMarker == null)
25436
- return;
25437
- saveDeviceLastSyncAt(new Date(userMarker.lastSyncAt));
25438
- };
25439
25625
  /**
25440
25626
  * list of conditions that make timer still trigger the syncing process.
25441
25627
  * If it's empty, it means sync is stopped.
@@ -25500,43 +25686,11 @@ const markerSyncTrigger = async () => {
25500
25686
  }
25501
25687
  }
25502
25688
  };
25503
- const registerEventListeners = () => {
25504
- if (disposers$1.length > 0) {
25505
- return;
25506
- }
25507
- // based on the tech spec design, we designed a fetch marker in case of these events
25508
- // - new message
25509
- // - create channel
25510
- // - remove channel
25511
- // - app going to online again after offline
25512
- disposers$1.push(onOnline(() => {
25513
- // should add RESUME to the event to trigger marker syncing again
25514
- events.push("resume" /* Amity.MarkerSyncEvent.RESUME */);
25515
- }), onMessageCreatedMqtt(message => {
25516
- // only conversation, community and broadcast types can sync
25517
- const client = getActiveClient();
25518
- if (isUnreadCountSupport$1(message) && message.creatorId !== client.userId)
25519
- events.push("new message" /* Amity.MarkerSyncEvent.NEW_MESSAGE */);
25520
- }), onChannelCreated(() => events.push("subchannel is created" /* Amity.MarkerSyncEvent.CHANNEL_CREATED */)), onChannelDeleted(() => events.push("subchannel is deleted" /* Amity.MarkerSyncEvent.CHANNEL_DELETED */)), onChannelJoined(() => events.push("subchannel is joined" /* Amity.MarkerSyncEvent.CHANNEL_JOINED */)), onChannelLeft(() => events.push("subchannel is left" /* Amity.MarkerSyncEvent.CHANNEL_LEFT */)), onSubChannelCreated(() => events.push("subchannel is created" /* Amity.MarkerSyncEvent.SUB_CHANNEL_CREATED */)), onSubChannelDeleted(() =>
25521
- /*
25522
- workaround: when receiving the event for sub-channel deletion,
25523
- before triggering marker update, the SDK will have to add a 2-second delay.
25524
- so that the unread count is calculated correctly.
25525
- */
25526
- setTimeout(() => events.push("subchannel is deleted" /* Amity.MarkerSyncEvent.SUBCHANNEL_IS_DELETED */), ON_SUB_CHANNEL_DELETE_SYNC_TRIGGER_DELAY)), onFeedMarkerUpdated(() => events.push("feed marker updated" /* Amity.MarkerSyncEvent.MARKER_UPDATED */)), onUserMarkerSync(() => events.push("feed marker updated" /* Amity.MarkerSyncEvent.MARKER_UPDATED */)), onUserFeedMarkerUpdated(() => events.push("feed marker updated" /* Amity.MarkerSyncEvent.MARKER_UPDATED */)));
25527
- };
25528
25689
  const unRegisterEventListeners = () => {
25529
25690
  disposers$1.forEach(fn => fn());
25530
25691
  disposers$1 = [];
25531
25692
  };
25532
- const startMarkerSync = async () => {
25533
- await fetchDeviceLastSyncAt();
25534
- pushMarkerSyncEvent("start syncing" /* Amity.MarkerSyncEvent.START_SYNCING */);
25535
- isConsistentMode = true;
25536
- isSyncRunning = true;
25537
- registerEventListeners();
25538
- return unRegisterEventListeners;
25539
- };
25693
+ const startMarkerSync = async () => Promise.resolve();
25540
25694
  /**
25541
25695
  ```js
25542
25696
  * import { startUnreadSync } from '@amityco/ts-sdk-react-native'
@@ -25548,14 +25702,7 @@ const startMarkerSync = async () => {
25548
25702
  *
25549
25703
  * @category Marker API
25550
25704
  */
25551
- const startUnreadSync = async () => {
25552
- await fetchDeviceLastSyncAt();
25553
- pushMarkerSyncEvent("start syncing" /* Amity.MarkerSyncEvent.START_SYNCING */);
25554
- enableUnreadCount();
25555
- isConsistentMode = false;
25556
- isSyncRunning = true;
25557
- registerEventListeners();
25558
- };
25705
+ const startUnreadSync = async () => Promise.resolve();
25559
25706
  /**
25560
25707
  ```js
25561
25708
  * import { stopUnreadSync } from '@amityco/ts-sdk-react-native'
@@ -25578,268 +25725,6 @@ setIntervalTask(async () => {
25578
25725
  }, SYNC_TRIGGER_INTERVAL_TIME);
25579
25726
  const getMarkerSyncConsistentMode = () => isConsistentMode;
25580
25727
 
25581
- /* eslint-disable no-param-reassign */
25582
- /*
25583
- * declared earlier to accomodate case when logging in with a different user
25584
- * than the one already connected, in which case the existing subscriptions need
25585
- * to be cleared
25586
- */
25587
- let subscriptions = [];
25588
- async function runMqtt() {
25589
- await modifyMqttConnection();
25590
- }
25591
- /* begin_public_function
25592
- id: client.login
25593
- */
25594
- /**
25595
- * ```js
25596
- * import { login } from '@amityco/ts-sdk-react-native/client/api'
25597
- * const success = await login({
25598
- * userId: 'XYZ123456789',
25599
- * })
25600
- * ```
25601
- *
25602
- * Connects an {@link Amity.Client} instance to ASC servers
25603
- *
25604
- * @param params the connect parameters
25605
- * @param params.userId the user ID for the current session
25606
- * @param params.displayName the user's displayName for the current session
25607
- * @param params.deviceId Manual override of the user's device id (for device management)
25608
- * @param params.authToken The authentication token - necessary when network option is set to secure
25609
- * @returns a success boolean if connected
25610
- *
25611
- * @category Client API
25612
- * @async
25613
- */
25614
- const login = async (params, sessionHandler, config) => {
25615
- var _a;
25616
- const client = getActiveClient();
25617
- let unsubWatcher;
25618
- client.log('client/api/connectClient', Object.assign({ apiKey: client.apiKey, sessionState: client.sessionState }, params));
25619
- // if connecting to a different userId than the one that is connected currently
25620
- if (client.userId && client.userId !== params.userId) {
25621
- await logout();
25622
- // Remove subscription to ban and delete
25623
- subscriptions.forEach(fn => fn());
25624
- subscriptions = [];
25625
- }
25626
- // default values
25627
- const defaultDeviceId = await getDeviceId();
25628
- try {
25629
- const { users } = await setClientToken({
25630
- params: Object.assign(Object.assign({}, params), { displayName: params === null || params === void 0 ? void 0 : params.displayName, deviceId: (params === null || params === void 0 ? void 0 : params.deviceId) || defaultDeviceId }),
25631
- options: {
25632
- setAccessTokenCookie: true,
25633
- },
25634
- });
25635
- const user = users.find(u => u.userId === params.userId);
25636
- if (user == null) {
25637
- throw new ASCError(`${params.userId} has not been founded`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
25638
- }
25639
- if (user.isDeleted) {
25640
- terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
25641
- return false;
25642
- }
25643
- if (user.isGlobalBanned) {
25644
- terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
25645
- return false;
25646
- }
25647
- // FIXME: events are duplicated if connectClient is called few times without disconnectClient
25648
- // wire websocket events to our event emitter
25649
- proxyWebsocketEvents(client.ws, client.emitter);
25650
- (_a = client.ws) === null || _a === void 0 ? void 0 : _a.open();
25651
- client.userId = user.userId;
25652
- client.sessionHandler = sessionHandler;
25653
- /*
25654
- * Cannot push to subscriptions as watcher needs to continue working even if
25655
- * token expires
25656
- */
25657
- unsubWatcher = client.accessTokenExpiryWatcher(sessionHandler);
25658
- setActiveUser(user);
25659
- }
25660
- catch (error) {
25661
- /*
25662
- * if getting token failed session state reverts to initial state when app
25663
- * is first launched
25664
- */
25665
- SessionWatcher$1.getInstance().setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
25666
- // pass error down tree so the calling function handle it
25667
- throw error;
25668
- }
25669
- if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
25670
- runMqtt();
25671
- }
25672
- await initializeMessagePreviewSetting();
25673
- if (subscriptions.length === 0) {
25674
- subscriptions.push(
25675
- // GLOBAL_BAN
25676
- onClientBanned((_) => {
25677
- terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
25678
- subscriptions.forEach(fn => fn());
25679
- unsubWatcher();
25680
- }), onTokenTerminated(_ => {
25681
- terminateClient();
25682
- subscriptions.forEach(fn => fn());
25683
- unsubWatcher();
25684
- }), onUserDeleted$2((user) => {
25685
- if (user.userId === client.userId) {
25686
- terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
25687
- subscriptions.forEach(fn => fn());
25688
- unsubWatcher();
25689
- }
25690
- }), onTokenExpired(state => {
25691
- SessionWatcher$1.getInstance().setSessionState(state);
25692
- logout();
25693
- subscriptions.forEach(fn => fn());
25694
- }),
25695
- // NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
25696
- // the channel because currently backend can't handle this, so every time a user is banned from
25697
- // a channel or the channel is deleted the channel's unread count will not be reset to zero
25698
- onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler());
25699
- if (client.useLegacyUnreadCount) {
25700
- subscriptions.push(readReceiptSyncEngineOnLoginHandler());
25701
- }
25702
- else
25703
- subscriptions.push(legacyReadReceiptSyncEngineOnLoginHandler());
25704
- const markerSyncUnsubscriber = await startMarkerSync();
25705
- subscriptions.push(markerSyncUnsubscriber);
25706
- }
25707
- return true;
25708
- };
25709
- /* end_public_function */
25710
-
25711
- /* begin_public_function
25712
- id: client.renew_access_token
25713
- */
25714
- /*
25715
- * Renewal defintion accepted by SessionHandler interface
25716
- *
25717
- * Tech Spec:
25718
- * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Session-Handler
25719
- *
25720
- * @category private
25721
- */
25722
- const renewal = () => {
25723
- let tokenRenewed = false;
25724
- let renewTimeoutId;
25725
- const client = getActiveClient();
25726
- client.log('initiating access token renewal');
25727
- /*
25728
- * Renews a token if it is hasn't been renewed before. Also marks token as
25729
- * renewed once done
25730
- * Per instance of Renewal, only one renewal is allowed
25731
- */
25732
- const renewToken = async (authToken) => {
25733
- const { userId, displayName } = getActiveUser();
25734
- const deviceId = await getDeviceId();
25735
- const params = { userId, displayName, authToken, deviceId };
25736
- if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.sessionHandler) {
25737
- await login(params, client.sessionHandler);
25738
- }
25739
- else {
25740
- // about to expire
25741
- await setClientToken({
25742
- params,
25743
- options: {
25744
- setAccessTokenCookie: true,
25745
- },
25746
- });
25747
- }
25748
- tokenRenewed = true;
25749
- if (renewTimeoutId)
25750
- clearTimeout(renewTimeoutId);
25751
- };
25752
- return {
25753
- renew: () => {
25754
- if (tokenRenewed) {
25755
- console.log("'renew' method can be called only once per renewal instance");
25756
- return;
25757
- }
25758
- renewToken();
25759
- },
25760
- renewWithAuthToken: (authToken) => {
25761
- if (tokenRenewed) {
25762
- console.log("'renewWithAuthToken' method can be called only once per renewal instance");
25763
- return;
25764
- }
25765
- renewToken(authToken);
25766
- },
25767
- unableToRetrieveAuthToken: () => {
25768
- renewTimeoutId = setTimeout(() => {
25769
- var _a;
25770
- (_a = client.sessionHandler) === null || _a === void 0 ? void 0 : _a.sessionWillRenewAccessToken(renewal());
25771
- }, ACCESS_TOKEN_WATCHER_INTERVAL);
25772
- },
25773
- };
25774
- };
25775
- /* end_public_function */
25776
-
25777
- const ABOUT_TO_EXPIRE_THRESHOLD = 80 / 100;
25778
- const COMPENSATED_DELAY = 5 * MINUTE;
25779
- /*
25780
- * a helper function to check if the token has expires
25781
- *
25782
- * @param token to be checked
25783
- * @returns boolean indicating if token expires
25784
- *
25785
- * @category private
25786
- */
25787
- const isExpired = (expiresAt) => Date.now() > Date.parse(expiresAt) - COMPENSATED_DELAY;
25788
- /*
25789
- * a helper function to check if the token is about to expire
25790
- *
25791
- * @param token to be checked
25792
- * @returns boolean indicating if token is aboutToExpire
25793
- *
25794
- * @category private
25795
- */
25796
- const isAboutToExpire = (params) => {
25797
- const { expiresAt, issuedAt } = params;
25798
- const expires = Date.parse(expiresAt);
25799
- const issued = Date.parse(issuedAt);
25800
- const now = Date.now();
25801
- const duration = expires - issued - COMPENSATED_DELAY;
25802
- const aboutToExpireAt = issued + duration * ABOUT_TO_EXPIRE_THRESHOLD;
25803
- return now > aboutToExpireAt && now < expires;
25804
- };
25805
- /*
25806
- * Monitors time to expire of token and updates session state to aboutToExpire
25807
- *
25808
- * @returns intervalId to be cleared after trigger
25809
- *
25810
- * @category private
25811
- */
25812
- const accessTokenExpiryWatcher = (sessionHandler) => {
25813
- const interval = setInterval(() => {
25814
- const client = getActiveClient();
25815
- if (!client.token)
25816
- return;
25817
- const { issuedAt, expiresAt } = client.token;
25818
- if (isExpired(expiresAt)) {
25819
- /*
25820
- * the event handler will take care of updating session state
25821
- * Note, this will also clear the interval id, so this event will only be
25822
- * fired once
25823
- */
25824
- fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
25825
- /*
25826
- * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Automatically-initiate-renewal-flow
25827
- *
25828
- * Why sechduled task?
25829
- * Since fireEvent is scheduled, it will be called
25830
- * after sessionHandler leading to an invalid state change from
25831
- * establishing to tokenExpired
25832
- */
25833
- scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
25834
- return;
25835
- }
25836
- if (isAboutToExpire({ expiresAt, issuedAt })) {
25837
- sessionHandler.sessionWillRenewAccessToken(renewal());
25838
- }
25839
- }, ACCESS_TOKEN_WATCHER_INTERVAL);
25840
- return () => clearInterval(interval);
25841
- };
25842
-
25843
25728
  /**
25844
25729
  * ```js
25845
25730
  * import { Client } from '@amityco/ts-sdk'
@@ -26006,6 +25891,10 @@ const isConnected = () => {
26006
25891
  isWsConnected);
26007
25892
  };
26008
25893
 
25894
+ const enableUnreadCount = () => {
25895
+ return true;
25896
+ };
25897
+
26009
25898
  var _GlobalFileAccessType_fileAccessType;
26010
25899
  class GlobalFileAccessType {
26011
25900
  constructor() {
@@ -29449,7 +29338,7 @@ const prepareCommentFromFlaggedEvent = (payload) => {
29449
29338
  * @async
29450
29339
  * */
29451
29340
  const addReaction = async (referenceType, referenceId, reactionName) => {
29452
- var _a, _b;
29341
+ var _a, _b, _c;
29453
29342
  const client = getActiveClient();
29454
29343
  client.log('reaction/createReaction', {
29455
29344
  referenceId,
@@ -29470,9 +29359,9 @@ const addReaction = async (referenceType, referenceId, reactionName) => {
29470
29359
  'get',
29471
29360
  referenceId,
29472
29361
  ]);
29473
- if (!model)
29362
+ if (!model || ((_a = model.data.myReactions) === null || _a === void 0 ? void 0 : _a.includes(reactionName)))
29474
29363
  return true;
29475
- const updatedModel = Object.assign(Object.assign({}, model.data), { reactionsCount: model.data.reactionsCount + 1, myReactions: [...((_a = model.data.myReactions) !== null && _a !== void 0 ? _a : []), reactionName], reactions: Object.assign(Object.assign({}, model.data.reactions), { [reactionName]: ((_b = model.data.reactions[reactionName]) !== null && _b !== void 0 ? _b : 0) + 1 }) });
29364
+ const updatedModel = Object.assign(Object.assign({}, model.data), { reactionsCount: model.data.reactionsCount + 1, myReactions: [...((_b = model.data.myReactions) !== null && _b !== void 0 ? _b : []), reactionName], reactions: Object.assign(Object.assign({}, model.data.reactions), { [reactionName]: ((_c = model.data.reactions[reactionName]) !== null && _c !== void 0 ? _c : 0) + 1 }) });
29476
29365
  if (referenceType === 'comment') {
29477
29366
  fireEvent('local.comment.addReaction', {
29478
29367
  comment: updatedModel,
@@ -40717,7 +40606,7 @@ var index$4 = /*#__PURE__*/Object.freeze({
40717
40606
  getPoll: getPoll
40718
40607
  });
40719
40608
 
40720
- const privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDAARz+hmBgi8pJ\nQb8LeY41gtHhk+ACMwRfhsn7GqpqRQNG2qU0755mzZuVDUqjQMGSo8THJB7O+OJs\nflbZRkFXlFoFOVNw1UpNOgwEQZ6wB9oRwzepTJAfF1sVhm/o/ixvXh1zDFNDy6yZ\npXyiiJHUVxqyjllZhxnwdvjoVtDs6hW6awG09bB9nh/TTejlUKXoAgzqVwu/1QMu\nUVViET495elEe19aUarEy+oL2iKeXCEvqda/pWNBdbieFyJvvZ08HN8dPuT88wq2\njZLEAth1vrwQ2IAa4ktaLcBQdLJgIkrbDvAiVZ8lQAjS/bq5vXQikTGvoPlC5bbn\nvuOM/3eLAgMBAAECggEAVZ+peHAghq2QVj71nX5lxsNCKaCyYwixSJBpfouTt7Rz\nE6PpzMOXFi1W1o+I22jDakuSM2SOQKqI/u0QefB0r0O/KVk5NrZHXk0mkrdYtxOp\nUgaGyf8UvmjB+8VqHrNKyZdk9qtmbnNj01kTTcAtmE4H39zPR7eR/8Rul94vaZbs\nwCnKJS3mLT3JxyGug6lxanveKkjG+CKC1nJQYWaxCJxaFSzbwXQPvDhB+TvrIbee\npd5v4EAyEJohpr+T9oDGGJkb/KARBZCtwLyB976PKJwwBA8MRVL1i5QwawuMiMq5\nUtnOnbGKtCeFzaLbNU0Qi8bqyims84EQxC6DOu1fkQKBgQDdvsoBsEhsOXV7hlIJ\naEd0eSJZVkdqimxH8uGoMM2FeNaOrcB6yBXqTSP0R3OIyf8eaY6yjRvP30ZNXcll\n/gD3O1Mu6YmWQdt1W2WA6pKOsUuPXasf0pdOF7IiFZKlSabz5YHXFqwVuqm8loaj\nsXel3YWqPVdHiankE7tz+3ssnQKBgQDdqi4TNdD1MdEpihx19jr0QjUiXW3939FK\nqp30HESPEGDGQzXdmJgif9HhZb+cJSuWaHEbjgBrYahvgCF+y6LbEpOD+D/dmT+s\nDEAQaR84sah6dokwPjV8fjBSrcVFjCS+doxv0d3p/9OUEeyUhFrY03nxtIEYkLIE\n/Zvn37b4RwKBgQCLENVFe9XfsaVhQ5r9dV2iyTlmh7qgMZG5CbTFs12hQGhm8McO\n+Z7s41YSJCFr/yq1WwP4LJDtrBw99vyQr1zRsG35tNLp3gGRNzGQSQyC2uQFVHw2\np+7mNewsfhUK/gbrXNsyFnDz6635rPlhfbII3sWuP2wWXFqkxE9CbMwR7QKBgQC6\nawDMzxmo2/iYArrkyevSuEuPVxvFwpF1RgAI6C0QVCnPE38dmdN4UB7mfHekje4W\nVEercMURidPp0cxZolCYBQtilUjAyL0vqC3In1/Ogjq6oy3FEMxSop1pKxMY5j+Q\nnoqFD+6deLUrddeNH7J3X4LSr4dSbX4JjG+tlgt+yQKBgQCuwTL4hA6KqeInQ0Ta\n9VQX5Qr8hFlqJz1gpymi/k63tW/Ob8yedbg3WWNWyShwRMFYyY9S81ITFWM95uL6\nvF3x9rmRjwElJw9PMwVu6dmf/CO0Z1wzXSp2VVD12gbrUD/0/d7MUoJ9LgC8X8f/\nn0txLHYGHbx+nf95+JUg6lV3hg==\n-----END PRIVATE KEY-----";
40609
+ const privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHo80SecH7FuF2\nhFYnb+l26/VN8UMLXAQFLnxciNTEwkGVFMpdezlH8rU2HtUJL4RETogbAOLVY0XM\njs6sPn8G1nALmh9qeDpUtVqFOVtBHxEZ910TLOtQiunjqJKO5nWdqZ71EC3OFluR\niGQkO84BiIFbv37ub7xl3S8XarbtKoLcyVpkDHi+1wx1pgCAn6gtBUgckPL5NR8j\nLseabl3HAXQfhTCKo4tmOFM2Dxwl1IUMmIJrJg/aIU/U0tj/1Eoo7mG0JcNWX19l\nW3EecCbi0ncCJOrkUdwlBrcjaMayaX/ubEwyUeTGiLdyc4L3GRLHjyK8xgVNXRMH\nbZWJ2a5NAgMBAAECggEASxuE+35zTFO/XydKgmvIGcWL9FbgMlXb7Vcf0nBoG945\nbiz0NVc2paraIhJXc608xbYF3qLmtAE1MVBI0ORyRdBHNxY024l/6H6SH60Ed+uI\nM4ysp5ourY6Vj+DLwpdRiI9YDjqYAQDIUmhNxJP7XPhOMoZI6st+xZQBM34ic/bv\nAMSJm9OZphSp3+qXVkFZztr2mxD2EZSJJLYxi8BCdgM2qhazalbcJ6zDKHCZWVWm\n8RRxDGldyMb/237JxETzP40tAlzOZDmBAbUgEnurDJ93RVDIE3rbZUshwgeQd18a\nem096mWgvB1AIKYgsTAR3pw+V19YWAjq/glP6fz8wQKBgQD/oQq+ukKF0PRgBeM5\ngeTjSwsdGppQLmf5ndujvoiz/TpdjDEPu6R8kigQr1rG2t4K/yfdZoI8RdmJD1al\n3Q7N9hofooSy4rj6E3txzWZCHJjHad2cnCp/O26HiReGAl7wTcfTmNdiFHhZQzm5\nJBkvWAiwuvQMNfEbnXxw6/vIDwKBgQDH7fX8gsc77JLvAWgp1MaQN/sbqVb6JeT1\nFQfR8E/WFCSmzQBtNzd5KgYuCeelwr/8DyYytvN2BzCYZXp73gI1jF3YlW5jVn74\nOY6TwQ095digwo6Z0yuxopdIOApKgAkL9PRKgNrqAf3NAyMua6lOGifzjDojC3KU\nfylQmxMn4wKBgHp2B9O/H0dEBw5JQ8W0+JX6yWQz7mEjGiR2/1W+XXb8hQ1zr709\nw1r6Gb+EghRpnZ3fBpYGGbYOMFx8wKHM+N6qW3F0ReX8v2juFGE8aRSa5oYBrWzt\nU16Idjbv8hj84cZ1PJmdyvDtpYn9rpWHOZl4rxEbPvbqkIsOMyNVqdT5AoGAOSge\nmwIIU2le2FVeohbibXiToWTYKMuMmURZ5/r72AgKMmWJKbAPe+Q3wBG01/7FRBpQ\noU8Ma0HC8s6QJbliiEyIx9JwrJWd1vkdecBHONrtA4ibm/5zD2WcOllLF+FitLhi\n3qnX6+6F0IaFGFBPJrTzlv0P4dTz/OAdv52V7GECgYEA2TttOKBAqWllgOaZOkql\nLVMJVmgR7s6tLi1+cEP8ZcapV9aRbRzTAKXm4f8AEhtlG9F9kCOvHYCYGi6JaiWJ\nZkHjeex3T+eE6Di6y5Bm/Ift5jtVhJ4jCVwHOKTMej79NPUFTJfv8hCo29haBDv6\nRXFrv+T21KCcw8k3sJeJWWQ=\n-----END PRIVATE KEY-----";
40721
40610
  /*
40722
40611
  * The crypto algorithm used for importing key and signing string
40723
40612
  */