@amityco/ts-sdk 7.11.1-fec87c5.0 → 7.12.1-27702e75.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/@types/core/events.d.ts +5 -4
  2. package/dist/@types/core/events.d.ts.map +1 -1
  3. package/dist/@types/core/linkPreviewMetadata.d.ts +12 -0
  4. package/dist/@types/core/linkPreviewMetadata.d.ts.map +1 -0
  5. package/dist/@types/domains/community.d.ts +2 -7
  6. package/dist/@types/domains/community.d.ts.map +1 -1
  7. package/dist/@types/domains/liveStreamPlayer.d.ts +6 -2
  8. package/dist/@types/domains/liveStreamPlayer.d.ts.map +1 -1
  9. package/dist/@types/domains/post.d.ts +10 -0
  10. package/dist/@types/domains/post.d.ts.map +1 -1
  11. package/dist/@types/domains/room.d.ts +41 -2
  12. package/dist/@types/domains/room.d.ts.map +1 -1
  13. package/dist/client/api/fetchLinkPreview.d.ts +3 -0
  14. package/dist/client/api/fetchLinkPreview.d.ts.map +1 -1
  15. package/dist/client/api/getLinkPreviewMetadata.d.ts +14 -0
  16. package/dist/client/api/getLinkPreviewMetadata.d.ts.map +1 -0
  17. package/dist/client/api/index.d.ts +1 -0
  18. package/dist/client/api/index.d.ts.map +1 -1
  19. package/dist/core/events.d.ts +3 -3
  20. package/dist/core/events.d.ts.map +1 -1
  21. package/dist/eventRepository/internalApi/getEvent.d.ts.map +1 -1
  22. package/dist/index.cjs.js +922 -430
  23. package/dist/index.esm.js +902 -410
  24. package/dist/index.umd.js +3 -3
  25. package/dist/liveReactionRepository/api/createReaction.d.ts +7 -2
  26. package/dist/liveReactionRepository/api/createReaction.d.ts.map +1 -1
  27. package/dist/liveReactionRepository/internalApi/createLiveReaction.d.ts +3 -2
  28. package/dist/liveReactionRepository/internalApi/createLiveReaction.d.ts.map +1 -1
  29. package/dist/liveReactionRepository/service/ReactionSyncEngine.d.ts +2 -1
  30. package/dist/liveReactionRepository/service/ReactionSyncEngine.d.ts.map +1 -1
  31. package/dist/liveStreamPlayer/utils/cryptoSignatureUtils.d.ts +2 -2
  32. package/dist/liveStreamPlayer/utils/cryptoSignatureUtils.d.ts.map +1 -1
  33. package/dist/postRepository/api/createPost.d.ts +1 -0
  34. package/dist/postRepository/api/createPost.d.ts.map +1 -1
  35. package/dist/postRepository/api/editPost.d.ts +1 -0
  36. package/dist/postRepository/api/editPost.d.ts.map +1 -1
  37. package/dist/roomRepository/api/analytics/AmityRoomAnalytics.d.ts +30 -0
  38. package/dist/roomRepository/api/analytics/AmityRoomAnalytics.d.ts.map +1 -0
  39. package/dist/roomRepository/api/analytics/WatchSessionStorage.d.ts +38 -0
  40. package/dist/roomRepository/api/analytics/WatchSessionStorage.d.ts.map +1 -0
  41. package/dist/roomRepository/api/analytics/index.d.ts +4 -0
  42. package/dist/roomRepository/api/analytics/index.d.ts.map +1 -0
  43. package/dist/roomRepository/api/analytics/syncWatchSessions.d.ts +6 -0
  44. package/dist/roomRepository/api/analytics/syncWatchSessions.d.ts.map +1 -0
  45. package/dist/roomRepository/api/index.d.ts +1 -0
  46. package/dist/roomRepository/api/index.d.ts.map +1 -1
  47. package/dist/roomRepository/events/index.d.ts +2 -0
  48. package/dist/roomRepository/events/index.d.ts.map +1 -1
  49. package/dist/roomRepository/events/onRoomParticipantJoined.d.ts +1 -1
  50. package/dist/roomRepository/events/onRoomParticipantJoined.d.ts.map +1 -1
  51. package/dist/roomRepository/events/onRoomParticipantLeft.d.ts +1 -1
  52. package/dist/roomRepository/events/onRoomParticipantLeft.d.ts.map +1 -1
  53. package/dist/roomRepository/events/onRoomParticipantRemoved.d.ts +1 -1
  54. package/dist/roomRepository/events/onRoomParticipantRemoved.d.ts.map +1 -1
  55. package/dist/roomRepository/events/onRoomParticipantStageJoined.d.ts +17 -0
  56. package/dist/roomRepository/events/onRoomParticipantStageJoined.d.ts.map +1 -0
  57. package/dist/roomRepository/events/onRoomParticipantStageLeft.d.ts +17 -0
  58. package/dist/roomRepository/events/onRoomParticipantStageLeft.d.ts.map +1 -0
  59. package/dist/roomRepository/observers/getRoom.d.ts.map +1 -1
  60. package/dist/roomRepository/observers/getRooms/RoomLiveCollectionController.d.ts.map +1 -1
  61. package/dist/roomRepository/observers/utils.d.ts +1 -0
  62. package/dist/roomRepository/observers/utils.d.ts.map +1 -1
  63. package/dist/utils/linkedObject/roomLinkedObject.d.ts.map +1 -1
  64. package/package.json +1 -1
package/dist/index.esm.js CHANGED
@@ -224,8 +224,8 @@ var AmityEventOrderOption;
224
224
 
225
225
  function getVersion() {
226
226
  try {
227
- // the string ''v7.11.0-esm'' should be replaced by actual value by @rollup/plugin-replace
228
- return 'v7.11.0-esm';
227
+ // the string ''v7.12.0-esm'' should be replaced by actual value by @rollup/plugin-replace
228
+ return 'v7.12.0-esm';
229
229
  }
230
230
  catch (error) {
231
231
  return '__dev__';
@@ -24622,12 +24622,13 @@ var objectResolverEngineOnLoginHandler = () => {
24622
24622
  * @category Live Reaction API
24623
24623
  * @async
24624
24624
  */
24625
- const createLiveReaction = async ({ reactions, liveStreamId, }) => {
24625
+ const createLiveReaction = async ({ reactions, liveStreamId, roomId, }) => {
24626
24626
  const client = getActiveClient();
24627
24627
  client.log('live_reaction/addReaction', reactions);
24628
24628
  const { data } = await client.http.post(`/api/v1/reactions/live`, {
24629
24629
  liveStreamId,
24630
24630
  reactions,
24631
+ roomId,
24631
24632
  });
24632
24633
  return data;
24633
24634
  };
@@ -24684,19 +24685,23 @@ class LiveReactionSyncEngine {
24684
24685
  // Clear buffer
24685
24686
  this.clearBuffer();
24686
24687
  const payloads = reactions.reduce((prev, curr) => {
24687
- const { roomId } = curr, rest = __rest(curr, ["roomId"]);
24688
- if (!prev[roomId]) {
24688
+ const { roomId, streamId } = curr, rest = __rest(curr, ["roomId", "streamId"]);
24689
+ const referenceType = streamId ? 'liveStream' : 'room';
24690
+ const referenceId = streamId !== null && streamId !== void 0 ? streamId : roomId;
24691
+ if (!prev[referenceId]) {
24689
24692
  // eslint-disable-next-line no-param-reassign
24690
- prev[roomId] = [rest];
24693
+ prev[referenceId] = { referenceType, reactions: [] };
24694
+ prev[referenceId].reactions.push(rest);
24691
24695
  }
24692
24696
  else
24693
- prev[roomId].push(rest);
24697
+ prev[referenceId].reactions.push(rest);
24694
24698
  return prev;
24695
24699
  }, {});
24696
24700
  // Call server api `POST /api/v1/reactions/live` to sync live reactions
24697
- Object.entries(payloads).forEach(([roomId, reactions]) => {
24701
+ Object.entries(payloads).forEach(([referenceId, reactionPayload]) => {
24702
+ const referenceIdName = reactionPayload.referenceType === 'room' ? 'roomId' : 'liveStreamId';
24698
24703
  createLiveReaction({
24699
- liveStreamId: roomId,
24704
+ [referenceIdName]: referenceId,
24700
24705
  reactions,
24701
24706
  });
24702
24707
  });
@@ -26087,6 +26092,9 @@ function setUploadedFileAccessType(accessType) {
26087
26092
  GlobalFileAccessType$1.getInstance().setFileAccessType(accessType);
26088
26093
  }
26089
26094
 
26095
+ /**
26096
+ * @deprecated This function will to be deprecated and use the new getLinkPreviewMetadata
26097
+ */
26090
26098
  /**
26091
26099
  * ```js
26092
26100
  * import { fetchLinkPreview } from '@amityco/ts-sdk'
@@ -26109,6 +26117,24 @@ const fetchLinkPreview = async (url) => {
26109
26117
  return data;
26110
26118
  };
26111
26119
 
26120
+ /**
26121
+ * ```js
26122
+ * import { getLinkPreviewMetadata } from '@amityco/ts-sdk'
26123
+ * const { title, description, imageUrl } = getLinkPreviewMetadata('https://www.example.com/')
26124
+ * ```
26125
+ *
26126
+ *
26127
+ * @param url the url to fetch link preview
26128
+ * @returns A {@link Amity.LinkPreviewMetadata} instance
26129
+ *
26130
+ * @category Client API
26131
+ * */
26132
+ const getLinkPreviewMetadata = async (url) => {
26133
+ const client = getActiveClient();
26134
+ const { data } = await client.http.get(`/api/v1/link-preview?url=${url}`);
26135
+ return data;
26136
+ };
26137
+
26112
26138
  /**
26113
26139
  * ```js
26114
26140
  * import Client from '@amityco/ts-sdk'
@@ -26638,6 +26664,7 @@ var index$r = /*#__PURE__*/Object.freeze({
26638
26664
  enableUnreadCount: enableUnreadCount,
26639
26665
  setUploadedFileAccessType: setUploadedFileAccessType,
26640
26666
  fetchLinkPreview: fetchLinkPreview,
26667
+ getLinkPreviewMetadata: getLinkPreviewMetadata,
26641
26668
  getSocialSettings: getSocialSettings,
26642
26669
  getShareableLinkConfiguration: getShareableLinkConfiguration,
26643
26670
  loginAsVisitor: loginAsVisitor,
@@ -28538,12 +28565,9 @@ const rejectInvitation = async (invitationId) => {
28538
28565
  };
28539
28566
  /* end_public_function */
28540
28567
 
28541
- var InvitationActionsEnum;
28542
- (function (InvitationActionsEnum) {
28543
- InvitationActionsEnum["OnLocalInvitationCreated"] = "onLocalInvitationCreated";
28544
- InvitationActionsEnum["OnLocalInvitationUpdated"] = "onLocalInvitationUpdated";
28545
- InvitationActionsEnum["OnLocalInvitationCanceled"] = "onLocalInvitationCanceled";
28546
- })(InvitationActionsEnum || (InvitationActionsEnum = {}));
28568
+ const prepareMyInvitationsPayload = (rawPayload) => {
28569
+ return Object.assign(Object.assign({}, rawPayload), { users: rawPayload.users.map(convertRawUserToInternalUser), invitations: rawPayload.invitations.map(convertRawInvitationToInternalInvitation) });
28570
+ };
28547
28571
 
28548
28572
  const invitationLinkedObject = (invitation) => {
28549
28573
  return Object.assign(Object.assign({}, invitation), { get user() {
@@ -28577,274 +28601,6 @@ const invitationLinkedObject = (invitation) => {
28577
28601
  } });
28578
28602
  };
28579
28603
 
28580
- class InvitationsPaginationController extends PaginationController {
28581
- async getRequest(queryParams, token) {
28582
- const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT } = queryParams, params = __rest(queryParams, ["limit"]);
28583
- const options = token ? { token } : { limit };
28584
- const { data } = await this.http.get('/api/v1/invitations', { params: Object.assign(Object.assign({}, params), { options }) });
28585
- return data;
28586
- }
28587
- }
28588
-
28589
- class InvitationsQueryStreamController extends QueryStreamController {
28590
- constructor(query, cacheKey, notifyChange, preparePayload) {
28591
- super(query, cacheKey);
28592
- this.notifyChange = notifyChange;
28593
- this.preparePayload = preparePayload;
28594
- }
28595
- async saveToMainDB(response) {
28596
- const processedPayload = await this.preparePayload(response);
28597
- const client = getActiveClient();
28598
- const cachedAt = client.cache && Date.now();
28599
- if (client.cache) {
28600
- ingestInCache(processedPayload, { cachedAt });
28601
- }
28602
- }
28603
- appendToQueryStream(response, direction, refresh = false) {
28604
- var _a, _b;
28605
- if (refresh) {
28606
- pushToCache(this.cacheKey, {
28607
- data: response.invitations.map(getResolver('invitation')),
28608
- });
28609
- }
28610
- else {
28611
- const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
28612
- const invitations = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
28613
- pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [
28614
- ...new Set([...invitations, ...response.invitations.map(getResolver('invitation'))]),
28615
- ] }));
28616
- }
28617
- }
28618
- reactor(action) {
28619
- return (invitations) => {
28620
- var _a;
28621
- const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
28622
- if (!collection)
28623
- return;
28624
- if (action === InvitationActionsEnum.OnLocalInvitationUpdated) {
28625
- const isExist = collection.data.find(id => id === invitations[0].invitationId);
28626
- if (!isExist)
28627
- return;
28628
- }
28629
- if (action === InvitationActionsEnum.OnLocalInvitationCreated) {
28630
- collection.data = [
28631
- ...new Set([
28632
- ...invitations.map(invitation => invitation.invitationId),
28633
- ...collection.data,
28634
- ]),
28635
- ];
28636
- }
28637
- if (action === InvitationActionsEnum.OnLocalInvitationDeleted) {
28638
- collection.data = collection.data.filter(id => id !== invitations[0].invitationId);
28639
- }
28640
- pushToCache(this.cacheKey, collection);
28641
- this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
28642
- };
28643
- }
28644
- subscribeRTE(createSubscriber) {
28645
- return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
28646
- }
28647
- }
28648
-
28649
- /**
28650
- * ```js
28651
- * import { onLocalInvitationCreated } from '@amityco/ts-sdk'
28652
- * const dispose = onLocalInvitationCreated(data => {
28653
- * // ...
28654
- * })
28655
- * ```
28656
- *
28657
- * Fired when an {@link Amity.InvitationPayload} has been created
28658
- *
28659
- * @param callback The function to call when the event was fired
28660
- * @returns an {@link Amity.Unsubscriber} function to stop listening
28661
- *
28662
- * @category Invitation Events
28663
- */
28664
- const onLocalInvitationCreated = (callback) => {
28665
- const client = getActiveClient();
28666
- const disposers = [
28667
- createEventSubscriber(client, 'onLocalInvitationCreated', 'local.invitation.created', payload => callback(payload)),
28668
- ];
28669
- return () => {
28670
- disposers.forEach(fn => fn());
28671
- };
28672
- };
28673
-
28674
- /**
28675
- * ```js
28676
- * import { onLocalInvitationUpdated } from '@amityco/ts-sdk'
28677
- * const dispose = onLocalInvitationUpdated(data => {
28678
- * // ...
28679
- * })
28680
- * ```
28681
- *
28682
- * Fired when an {@link Amity.InvitationPayload} has been updated
28683
- *
28684
- * @param callback The function to call when the event was fired
28685
- * @returns an {@link Amity.Unsubscriber} function to stop listening
28686
- *
28687
- * @category Invitation Events
28688
- */
28689
- const onLocalInvitationUpdated = (callback) => {
28690
- const client = getActiveClient();
28691
- const disposers = [
28692
- createEventSubscriber(client, 'onLocalInvitationUpdated', 'local.invitation.updated', payload => callback(payload)),
28693
- ];
28694
- return () => {
28695
- disposers.forEach(fn => fn());
28696
- };
28697
- };
28698
-
28699
- /**
28700
- * ```js
28701
- * import { onLocalInvitationCanceled } from '@amityco/ts-sdk'
28702
- * const dispose = onLocalInvitationCanceled(data => {
28703
- * // ...
28704
- * })
28705
- * ```
28706
- *
28707
- * Fired when an {@link Amity.InvitationPayload} has been deleted
28708
- *
28709
- * @param callback The function to call when the event was fired
28710
- * @returns an {@link Amity.Unsubscriber} function to stop listening
28711
- *
28712
- * @category Invitation Events
28713
- */
28714
- const onLocalInvitationCanceled = (callback) => {
28715
- const client = getActiveClient();
28716
- const disposers = [
28717
- createEventSubscriber(client, 'onLocalInvitationCanceled', 'local.invitation.canceled', payload => callback(payload)),
28718
- ];
28719
- return () => {
28720
- disposers.forEach(fn => fn());
28721
- };
28722
- };
28723
-
28724
- class InvitationsLiveCollectionController extends LiveCollectionController {
28725
- constructor(query, callback) {
28726
- const queryStreamId = hash(query);
28727
- const cacheKey = ['invitation', 'collection', queryStreamId];
28728
- const paginationController = new InvitationsPaginationController(query);
28729
- super(paginationController, queryStreamId, cacheKey, callback);
28730
- this.query = query;
28731
- this.queryStreamController = new InvitationsQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), prepareInvitationPayload);
28732
- this.callback = callback.bind(this);
28733
- this.loadPage({ initial: true });
28734
- }
28735
- setup() {
28736
- var _a;
28737
- const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
28738
- if (!collection) {
28739
- pushToCache(this.cacheKey, {
28740
- data: [],
28741
- params: this.query,
28742
- });
28743
- }
28744
- }
28745
- async persistModel(queryPayload) {
28746
- await this.queryStreamController.saveToMainDB(queryPayload);
28747
- }
28748
- persistQueryStream({ response, direction, refresh, }) {
28749
- this.queryStreamController.appendToQueryStream(response, direction, refresh);
28750
- }
28751
- startSubscription() {
28752
- return this.queryStreamController.subscribeRTE([
28753
- {
28754
- fn: onLocalInvitationCreated,
28755
- action: InvitationActionsEnum.OnLocalInvitationCreated,
28756
- },
28757
- {
28758
- fn: onLocalInvitationUpdated,
28759
- action: InvitationActionsEnum.OnLocalInvitationUpdated,
28760
- },
28761
- {
28762
- fn: onLocalInvitationCanceled,
28763
- action: InvitationActionsEnum.OnLocalInvitationCanceled,
28764
- },
28765
- ]);
28766
- }
28767
- notifyChange({ origin, loading, error }) {
28768
- var _a, _b;
28769
- const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
28770
- if (!collection)
28771
- return;
28772
- const data = this.applyFilter((_b = collection.data
28773
- .map(id => pullFromCache(['invitation', 'get', id]))
28774
- .filter(isNonNullable)
28775
- .map(({ data }) => invitationLinkedObject(data))) !== null && _b !== void 0 ? _b : []);
28776
- if (!this.shouldNotify(data) && origin === 'event')
28777
- return;
28778
- this.callback({
28779
- onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
28780
- data,
28781
- hasNextPage: !!this.paginationController.getNextToken(),
28782
- loading,
28783
- error,
28784
- });
28785
- }
28786
- applyFilter(data) {
28787
- let invitations = data;
28788
- if (this.query.targetId) {
28789
- invitations = invitations.filter(invitation => invitation.targetId === this.query.targetId);
28790
- }
28791
- if (this.query.statuses) {
28792
- invitations = invitations.filter(invitation => { var _a; return (_a = this.query.statuses) === null || _a === void 0 ? void 0 : _a.includes(invitation.status); });
28793
- }
28794
- if (this.query.targetType) {
28795
- invitations = invitations.filter(invitation => invitation.targetType === this.query.targetType);
28796
- }
28797
- if (this.query.type) {
28798
- invitations = invitations.filter(invitation => invitation.type === this.query.type);
28799
- }
28800
- const sortFn = (() => {
28801
- switch (this.query.sortBy) {
28802
- case 'firstCreated':
28803
- return sortByFirstCreated;
28804
- case 'lastCreated':
28805
- return sortByLastCreated;
28806
- default:
28807
- return sortByLastCreated;
28808
- }
28809
- })();
28810
- invitations = invitations.sort(sortFn);
28811
- return invitations;
28812
- }
28813
- }
28814
-
28815
- /**
28816
- * Get invitations
28817
- *
28818
- * @param params the query parameters
28819
- * @param callback the callback to be called when the invitations are updated
28820
- * @returns invitations
28821
- *
28822
- * @category Invitation Live Collection
28823
- *
28824
- */
28825
- const getInvitations$1 = (params, callback, config) => {
28826
- const { log, cache } = getActiveClient();
28827
- if (!cache) {
28828
- console.log(ENABLE_CACHE_MESSAGE);
28829
- }
28830
- const timestamp = Date.now();
28831
- log(`getInvitations: (tmpid: ${timestamp}) > listen`);
28832
- const invitationsLiveCollection = new InvitationsLiveCollectionController(params, callback);
28833
- const disposers = invitationsLiveCollection.startSubscription();
28834
- const cacheKey = invitationsLiveCollection.getCacheKey();
28835
- disposers.push(() => {
28836
- dropFromCache(cacheKey);
28837
- });
28838
- return () => {
28839
- log(`getInvitations (tmpid: ${timestamp}) > dispose`);
28840
- disposers.forEach(fn => fn());
28841
- };
28842
- };
28843
-
28844
- const prepareMyInvitationsPayload = (rawPayload) => {
28845
- return Object.assign(Object.assign({}, rawPayload), { users: rawPayload.users.map(convertRawUserToInternalUser), invitations: rawPayload.invitations.map(convertRawInvitationToInternalInvitation) });
28846
- };
28847
-
28848
28604
  /* begin_public_function
28849
28605
  id: invitation.get
28850
28606
  */
@@ -28878,6 +28634,414 @@ const getInvitation = async (params) => {
28878
28634
  };
28879
28635
  /* end_public_function */
28880
28636
 
28637
+ /**
28638
+ * WatchSessionStorage manages watch session data in memory
28639
+ * Similar to UsageCollector for stream watch minutes
28640
+ */
28641
+ class WatchSessionStorage {
28642
+ constructor() {
28643
+ this.sessions = new Map();
28644
+ }
28645
+ /**
28646
+ * Add a new watch session
28647
+ */
28648
+ addSession(session) {
28649
+ this.sessions.set(session.sessionId, session);
28650
+ }
28651
+ /**
28652
+ * Get a watch session by sessionId
28653
+ */
28654
+ getSession(sessionId) {
28655
+ return this.sessions.get(sessionId);
28656
+ }
28657
+ /**
28658
+ * Update a watch session
28659
+ */
28660
+ updateSession(sessionId, updates) {
28661
+ const session = this.sessions.get(sessionId);
28662
+ if (session) {
28663
+ this.sessions.set(sessionId, Object.assign(Object.assign({}, session), updates));
28664
+ }
28665
+ }
28666
+ /**
28667
+ * Get all sessions with a specific sync state
28668
+ */
28669
+ getSessionsByState(state) {
28670
+ return Array.from(this.sessions.values()).filter(session => session.syncState === state);
28671
+ }
28672
+ /**
28673
+ * Delete a session
28674
+ */
28675
+ deleteSession(sessionId) {
28676
+ this.sessions.delete(sessionId);
28677
+ }
28678
+ /**
28679
+ * Get all pending sessions
28680
+ */
28681
+ getPendingSessions() {
28682
+ return this.getSessionsByState('PENDING');
28683
+ }
28684
+ /**
28685
+ * Get all syncing sessions
28686
+ */
28687
+ getSyncingSessions() {
28688
+ return this.getSessionsByState('SYNCING');
28689
+ }
28690
+ }
28691
+ // Singleton instance
28692
+ let storageInstance = null;
28693
+ const getWatchSessionStorage = () => {
28694
+ if (!storageInstance) {
28695
+ storageInstance = new WatchSessionStorage();
28696
+ }
28697
+ return storageInstance;
28698
+ };
28699
+
28700
+ const privateKey = "MIIEpQIBAAKCAQEAwAEc/oZgYIvKSUG/C3mONYLR4ZPgAjMEX4bJ+xqqakUDRtql\\nNO+eZs2blQ1Ko0DBkqPExyQezvjibH5W2UZBV5RaBTlTcNVKTToMBEGesAfaEcM3\\nqUyQHxdbFYZv6P4sb14dcwxTQ8usmaV8ooiR1Fcaso5ZWYcZ8Hb46FbQ7OoVumsB\\ntPWwfZ4f003o5VCl6AIM6lcLv9UDLlFVYhE+PeXpRHtfWlGqxMvqC9oinlwhL6nW\\nv6VjQXW4nhcib72dPBzfHT7k/PMKto2SxALYdb68ENiAGuJLWi3AUHSyYCJK2w7w\\nIlWfJUAI0v26ub10IpExr6D5QuW2577jjP93iwIDAQABAoIBAFWfqXhwIIatkFY+\\n9Z1+ZcbDQimgsmMIsUiQaX6Lk7e0cxOj6czDlxYtVtaPiNtow2pLkjNkjkCqiP7t\\nEHnwdK9DvylZOTa2R15NJpK3WLcTqVIGhsn/FL5owfvFah6zSsmXZParZm5zY9NZ\\nE03ALZhOB9/cz0e3kf/EbpfeL2mW7MApyiUt5i09ycchroOpcWp73ipIxvgigtZy\\nUGFmsQicWhUs28F0D7w4Qfk76yG3nqXeb+BAMhCaIaa/k/aAxhiZG/ygEQWQrcC8\\ngfe+jyicMAQPDEVS9YuUMGsLjIjKuVLZzp2xirQnhc2i2zVNEIvG6soprPOBEMQu\\ngzrtX5ECgYEA3b7KAbBIbDl1e4ZSCWhHdHkiWVZHaopsR/LhqDDNhXjWjq3AesgV\\n6k0j9EdziMn/HmmOso0bz99GTV3JZf4A9ztTLumJlkHbdVtlgOqSjrFLj12rH9KX\\nTheyIhWSpUmm8+WB1xasFbqpvJaGo7F3pd2Fqj1XR4mp5BO7c/t7LJ0CgYEA3aou\\nEzXQ9THRKYocdfY69EI1Il1t/d/RSqqd9BxEjxBgxkM13ZiYIn/R4WW/nCUrlmhx\\nG44Aa2Gob4Ahfsui2xKTg/g/3Zk/rAxAEGkfOLGoenaJMD41fH4wUq3FRYwkvnaM\\nb9Hd6f/TlBHslIRa2NN58bSBGJCyBP2b59+2+EcCgYEAixDVRXvV37GlYUOa/XVd\\nosk5Zoe6oDGRuQm0xbNdoUBoZvDHDvme7ONWEiQha/8qtVsD+CyQ7awcPfb8kK9c\\n0bBt+bTS6d4BkTcxkEkMgtrkBVR8Nqfu5jXsLH4VCv4G61zbMhZw8+ut+az5YX2y\\nCN7Frj9sFlxapMRPQmzMEe0CgYEAumsAzM8ZqNv4mAK65Mnr0rhLj1cbxcKRdUYA\\nCOgtEFQpzxN/HZnTeFAe5nx3pI3uFlRHq3DFEYnT6dHMWaJQmAULYpVIwMi9L6gt\\nyJ9fzoI6uqMtxRDMUqKdaSsTGOY/kJ6KhQ/unXi1K3XXjR+yd1+C0q+HUm1+CYxv\\nrZYLfskCgYEArsEy+IQOiqniJ0NE2vVUF+UK/IRZaic9YKcpov5Ot7Vvzm/MnnW4\\nN1ljVskocETBWMmPUvNSExVjPebi+rxd8fa5kY8BJScPTzMFbunZn/wjtGdcM10q\\ndlVQ9doG61A/9P3ezFKCfS4AvF/H/59LcSx2Bh28fp3/efiVIOpVd4Y=";
28701
+ /*
28702
+ * The crypto algorithm used for importing key and signing string
28703
+ */
28704
+ const ALGORITHM = {
28705
+ name: 'RSASSA-PKCS1-v1_5',
28706
+ hash: { name: 'SHA-256' },
28707
+ };
28708
+ /*
28709
+ * IMPORTANT!
28710
+ * If you are recieving key from other platforms use an online tool to convert
28711
+ * the PKCS1 to PKCS8. For instance the key from Android SDK is of the format
28712
+ * PKCS1.
28713
+ *
28714
+ * If recieving from the platform, verify if it's already in the expected
28715
+ * format. Otherwise the crypto.subtle.importKey will throw a DOMException
28716
+ */
28717
+ const PRIVATE_KEY_SIGNATURE = 'pkcs8';
28718
+ /*
28719
+ * Ensure that the private key in the .env follows this format
28720
+ */
28721
+ const PEM_HEADER = '-----BEGIN PRIVATE KEY-----';
28722
+ const PEM_FOOTER = '-----END PRIVATE KEY-----';
28723
+ /*
28724
+ * The crypto.subtle.sign function returns an ArrayBuffer whereas the server
28725
+ * expects a base64 string. This util helps facilitate that process
28726
+ */
28727
+ function base64FromArrayBuffer(buffer) {
28728
+ const uint8Array = new Uint8Array(buffer);
28729
+ let binary = '';
28730
+ uint8Array.forEach(byte => {
28731
+ binary += String.fromCharCode(byte);
28732
+ });
28733
+ return btoa(binary);
28734
+ }
28735
+ /*
28736
+ * Encode ASN.1 length field
28737
+ */
28738
+ function encodeLength(length) {
28739
+ if (length < 128) {
28740
+ return new Uint8Array([length]);
28741
+ }
28742
+ if (length < 256) {
28743
+ return new Uint8Array([0x81, length]);
28744
+ }
28745
+ // eslint-disable-next-line no-bitwise
28746
+ return new Uint8Array([0x82, (length >> 8) & 0xff, length & 0xff]);
28747
+ }
28748
+ /*
28749
+ * Convert PKCS1 private key to PKCS8 format
28750
+ * PKCS1 is RSA-specific format, PKCS8 is generic format that crypto.subtle requires
28751
+ * Android uses PKCS8EncodedKeySpec which expects PKCS8 format
28752
+ */
28753
+ function pkcs1ToPkcs8(pkcs1) {
28754
+ // Algorithm identifier for RSA
28755
+ const algorithmIdentifier = new Uint8Array([
28756
+ 0x30,
28757
+ 0x0d,
28758
+ 0x06,
28759
+ 0x09,
28760
+ 0x2a,
28761
+ 0x86,
28762
+ 0x48,
28763
+ 0x86,
28764
+ 0xf7,
28765
+ 0x0d,
28766
+ 0x01,
28767
+ 0x01,
28768
+ 0x01,
28769
+ 0x05,
28770
+ 0x00, // NULL
28771
+ ]);
28772
+ // Version (INTEGER 0)
28773
+ const version = new Uint8Array([0x02, 0x01, 0x00]);
28774
+ // OCTET STRING tag + length + pkcs1 data
28775
+ const octetStringTag = 0x04;
28776
+ const octetStringLength = encodeLength(pkcs1.length);
28777
+ // Calculate total content length (version + algorithm + octet string)
28778
+ const contentLength = version.length + algorithmIdentifier.length + 1 + octetStringLength.length + pkcs1.length;
28779
+ // SEQUENCE tag + length
28780
+ const sequenceTag = 0x30;
28781
+ const sequenceLength = encodeLength(contentLength);
28782
+ // Build the PKCS8 structure
28783
+ const pkcs8 = new Uint8Array(1 + sequenceLength.length + contentLength);
28784
+ let offset = 0;
28785
+ pkcs8[offset] = sequenceTag;
28786
+ offset += 1;
28787
+ pkcs8.set(sequenceLength, offset);
28788
+ offset += sequenceLength.length;
28789
+ pkcs8.set(version, offset);
28790
+ offset += version.length;
28791
+ pkcs8.set(algorithmIdentifier, offset);
28792
+ offset += algorithmIdentifier.length;
28793
+ pkcs8[offset] = octetStringTag;
28794
+ offset += 1;
28795
+ pkcs8.set(octetStringLength, offset);
28796
+ offset += octetStringLength.length;
28797
+ pkcs8.set(pkcs1, offset);
28798
+ return pkcs8;
28799
+ }
28800
+ async function importPrivateKey(keyString) {
28801
+ // Remove PEM headers if present and any whitespace
28802
+ let base64Key = keyString;
28803
+ if (keyString.includes(PEM_HEADER)) {
28804
+ base64Key = keyString
28805
+ .substring(PEM_HEADER.length, keyString.length - PEM_FOOTER.length)
28806
+ .replace(/\s/g, '');
28807
+ }
28808
+ else {
28809
+ base64Key = keyString.replace(/\s/g, '');
28810
+ }
28811
+ // Base64 decode to get binary data
28812
+ const binaryDerString = atob(base64Key);
28813
+ // Convert to Uint8Array for manipulation
28814
+ const pkcs1 = new Uint8Array(binaryDerString.length);
28815
+ for (let i = 0; i < binaryDerString.length; i += 1) {
28816
+ pkcs1[i] = binaryDerString.charCodeAt(i);
28817
+ }
28818
+ // Convert PKCS1 to PKCS8 (crypto.subtle requires PKCS8)
28819
+ const pkcs8 = pkcs1ToPkcs8(pkcs1);
28820
+ // Import the key
28821
+ const key = await crypto.subtle.importKey(PRIVATE_KEY_SIGNATURE, pkcs8.buffer, ALGORITHM, false, ['sign']);
28822
+ return key;
28823
+ }
28824
+ async function createSignature({ timestamp, rooms, }) {
28825
+ const dataStr = rooms
28826
+ .map(item => Object.keys(item)
28827
+ .sort()
28828
+ .map(key => `${key}=${item[key]}`)
28829
+ .join('&'))
28830
+ .join(';');
28831
+ /*
28832
+ * nonceStr needs to be unique for each request
28833
+ */
28834
+ const nonceStr = uuid$1.v4();
28835
+ const signStr = `nonceStr=${nonceStr}&timestamp=${timestamp}&data=${dataStr}==`;
28836
+ const encoder = new TextEncoder();
28837
+ const data = encoder.encode(signStr);
28838
+ const key = await importPrivateKey(privateKey);
28839
+ const sign = await crypto.subtle.sign(ALGORITHM, key, data);
28840
+ return { signature: base64FromArrayBuffer(sign), nonceStr };
28841
+ }
28842
+
28843
+ /**
28844
+ * Sync pending watch sessions to backend
28845
+ * This function implements the full sync flow with network resilience
28846
+ */
28847
+ async function syncWatchSessions() {
28848
+ const storage = getWatchSessionStorage();
28849
+ // Get all pending sessions
28850
+ const pendingSessions = storage.getPendingSessions();
28851
+ if (pendingSessions.length === 0) {
28852
+ return true;
28853
+ }
28854
+ try {
28855
+ const timestamp = new Date().toISOString();
28856
+ // Convert sessions to API format - always include all fields like syncUsage does
28857
+ const rooms = pendingSessions.map(session => ({
28858
+ sessionId: session.sessionId,
28859
+ roomId: session.roomId,
28860
+ watchSeconds: session.watchSeconds,
28861
+ startTime: session.startTime.toISOString(),
28862
+ endTime: session.endTime ? session.endTime.toISOString() : '',
28863
+ }));
28864
+ // Create signature (reuse from stream feature) - pass directly like syncUsage
28865
+ const signatureData = await createSignature({
28866
+ timestamp,
28867
+ rooms,
28868
+ });
28869
+ if (!signatureData || !signatureData.signature) {
28870
+ throw new Error('Signature is undefined');
28871
+ }
28872
+ // Update sync state to SYNCING
28873
+ pendingSessions.forEach(session => {
28874
+ storage.updateSession(session.sessionId, { syncState: 'SYNCING' });
28875
+ });
28876
+ const payload = {
28877
+ signature: signatureData.signature,
28878
+ nonceStr: signatureData.nonceStr,
28879
+ timestamp,
28880
+ rooms,
28881
+ };
28882
+ const client = getActiveClient();
28883
+ // Send to backend
28884
+ await client.http.post('/api/v3/user-event/room', payload);
28885
+ // Success - update to SYNCED
28886
+ pendingSessions.forEach(session => {
28887
+ storage.updateSession(session.sessionId, {
28888
+ syncState: 'SYNCED',
28889
+ syncedAt: new Date(),
28890
+ });
28891
+ });
28892
+ return true;
28893
+ }
28894
+ catch (err) {
28895
+ console.error('[SDK syncWatchSessions] ERROR caught:', (err === null || err === void 0 ? void 0 : err.message) || err);
28896
+ // Failure - update back to PENDING and increment retry count
28897
+ pendingSessions.forEach(session => {
28898
+ const currentSession = storage.getSession(session.sessionId);
28899
+ if (currentSession) {
28900
+ const newRetryCount = currentSession.retryCount + 1;
28901
+ if (newRetryCount >= 3) {
28902
+ // Delete session if retry count exceeds 3
28903
+ storage.deleteSession(session.sessionId);
28904
+ }
28905
+ else {
28906
+ // Update to PENDING with incremented retry count
28907
+ storage.updateSession(session.sessionId, {
28908
+ syncState: 'PENDING',
28909
+ retryCount: newRetryCount,
28910
+ });
28911
+ }
28912
+ }
28913
+ });
28914
+ return false;
28915
+ }
28916
+ }
28917
+
28918
+ /**
28919
+ * Room statuses that are considered watchable
28920
+ */
28921
+ const WATCHABLE_ROOM_STATUSES = ['live', 'recorded'];
28922
+ /**
28923
+ * Generate a random jitter delay between 5 and 30 seconds
28924
+ */
28925
+ const getJitterDelay = () => {
28926
+ const minDelay = 5000; // 5 seconds
28927
+ const maxDelay = 30000; // 30 seconds
28928
+ return Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
28929
+ };
28930
+ /**
28931
+ * Wait for network connection with timeout
28932
+ * @param maxWaitTime Maximum time to wait in milliseconds (default: 60000 = 60 seconds)
28933
+ * @returns Promise that resolves when network is available or timeout is reached
28934
+ */
28935
+ const waitForNetwork = (maxWaitTime = 60000) => {
28936
+ return new Promise(resolve => {
28937
+ // Simple check - if navigator.onLine is available, use it
28938
+ // Otherwise, assume network is available
28939
+ if (typeof navigator === 'undefined' || typeof navigator.onLine === 'undefined') {
28940
+ resolve();
28941
+ return;
28942
+ }
28943
+ const startTime = Date.now();
28944
+ const checkInterval = 1000; // 1 second
28945
+ const checkConnection = () => {
28946
+ if (navigator.onLine || Date.now() - startTime >= maxWaitTime) {
28947
+ resolve();
28948
+ }
28949
+ else {
28950
+ setTimeout(checkConnection, checkInterval);
28951
+ }
28952
+ };
28953
+ checkConnection();
28954
+ });
28955
+ };
28956
+ /**
28957
+ * AmityRoomAnalytics provides analytics capabilities for room watch sessions
28958
+ */
28959
+ class AmityRoomAnalytics {
28960
+ constructor(room) {
28961
+ this.storage = getWatchSessionStorage();
28962
+ this.client = getActiveClient();
28963
+ this.room = room;
28964
+ }
28965
+ /**
28966
+ * Create a new watch session for the current room
28967
+ * @param startedAt The timestamp when watching started
28968
+ * @returns Promise<string> sessionId unique identifier for this watch session
28969
+ * @throws ASCApiError if room is not in watchable state (not LIVE or RECORDED)
28970
+ */
28971
+ async createWatchSession(startedAt) {
28972
+ // Validate room status
28973
+ if (!WATCHABLE_ROOM_STATUSES.includes(this.room.status)) {
28974
+ throw new ASCApiError('room is not in watchable state', 500000 /* Amity.ServerError.BUSINESS_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
28975
+ }
28976
+ // Generate session ID with prefix
28977
+ const prefix = this.room.status === 'live' ? 'live_' : 'playback_';
28978
+ const sessionId = prefix + uuid$1.v4();
28979
+ // Create watch session entity
28980
+ const session = {
28981
+ sessionId,
28982
+ roomId: this.room.roomId,
28983
+ watchSeconds: 0,
28984
+ startTime: startedAt,
28985
+ endTime: null,
28986
+ syncState: 'PENDING',
28987
+ syncedAt: null,
28988
+ retryCount: 0,
28989
+ };
28990
+ // Persist to storage
28991
+ this.storage.addSession(session);
28992
+ return sessionId;
28993
+ }
28994
+ /**
28995
+ * Update an existing watch session with duration
28996
+ * @param sessionId The unique identifier of the watch session
28997
+ * @param duration The total watch duration in seconds
28998
+ * @param endedAt The timestamp when this update occurred
28999
+ * @returns Promise<void> Completion status
29000
+ */
29001
+ async updateWatchSession(sessionId, duration, endedAt) {
29002
+ const session = this.storage.getSession(sessionId);
29003
+ if (!session) {
29004
+ throw new Error(`Watch session ${sessionId} not found`);
29005
+ }
29006
+ // Update session
29007
+ this.storage.updateSession(sessionId, {
29008
+ watchSeconds: duration,
29009
+ endTime: endedAt,
29010
+ });
29011
+ }
29012
+ /**
29013
+ * Sync all pending watch sessions to backend
29014
+ * This function uses jitter delay and handles network resilience
29015
+ */
29016
+ syncPendingWatchSessions() {
29017
+ // Execute with jitter delay (5-30 seconds)
29018
+ const jitterDelay = getJitterDelay();
29019
+ this.client.log('room/RoomAnalytics: syncPendingWatchSessions called, jitter delay:', `${jitterDelay}ms`);
29020
+ setTimeout(async () => {
29021
+ this.client.log('room/RoomAnalytics: Jitter delay completed, starting sync process');
29022
+ try {
29023
+ // Reset any SYNCING sessions back to PENDING
29024
+ const syncingSessions = this.storage.getSyncingSessions();
29025
+ this.client.log('room/RoomAnalytics: SYNCING sessions to reset:', syncingSessions.length);
29026
+ syncingSessions.forEach(session => {
29027
+ this.storage.updateSession(session.sessionId, { syncState: 'PENDING' });
29028
+ });
29029
+ // Wait for network connection (max 60 seconds)
29030
+ await waitForNetwork(60000);
29031
+ this.client.log('room/RoomAnalytics: Network available');
29032
+ // Sync pending sessions
29033
+ this.client.log('room/RoomAnalytics: Calling syncWatchSessions()');
29034
+ await syncWatchSessions();
29035
+ this.client.log('room/RoomAnalytics: syncWatchSessions completed');
29036
+ }
29037
+ catch (error) {
29038
+ // Error is already handled in syncWatchSessions
29039
+ console.error('Failed to sync watch sessions:', error);
29040
+ }
29041
+ }, jitterDelay);
29042
+ }
29043
+ }
29044
+
28881
29045
  const roomLinkedObject = (room) => {
28882
29046
  return Object.assign(Object.assign({}, room), { get post() {
28883
29047
  var _a;
@@ -28917,13 +29081,16 @@ const roomLinkedObject = (room) => {
28917
29081
  targetType: 'room',
28918
29082
  targetId: room.roomId,
28919
29083
  userIds: [userId],
28920
- }), getInvitations: (params, callback) => getInvitations$1(Object.assign(Object.assign({}, params), { targetId: room.roomId, targetType: 'room', type: "livestreamCohostInvite" /* InvitationTypeEnum.LivestreamCohostInvite */ }), callback), getMyInvitation: async () => {
29084
+ }), getInvitations: async () => {
28921
29085
  const { data } = await getInvitation({
28922
29086
  targetId: room.roomId,
28923
29087
  targetType: 'room',
28924
29088
  type: "livestreamCohostInvite" /* InvitationTypeEnum.LivestreamCohostInvite */,
28925
29089
  });
28926
29090
  return data;
29091
+ }, analytics() {
29092
+ // Use 'this' to avoid creating a new room object
29093
+ return new AmityRoomAnalytics(this);
28927
29094
  } });
28928
29095
  };
28929
29096
 
@@ -29492,6 +29659,277 @@ const getJoinRequests = (params, callback, config) => {
29492
29659
  };
29493
29660
  };
29494
29661
 
29662
+ var InvitationActionsEnum;
29663
+ (function (InvitationActionsEnum) {
29664
+ InvitationActionsEnum["OnLocalInvitationCreated"] = "onLocalInvitationCreated";
29665
+ InvitationActionsEnum["OnLocalInvitationUpdated"] = "onLocalInvitationUpdated";
29666
+ InvitationActionsEnum["OnLocalInvitationCanceled"] = "onLocalInvitationCanceled";
29667
+ })(InvitationActionsEnum || (InvitationActionsEnum = {}));
29668
+
29669
+ class InvitationsPaginationController extends PaginationController {
29670
+ async getRequest(queryParams, token) {
29671
+ const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT } = queryParams, params = __rest(queryParams, ["limit"]);
29672
+ const options = token ? { token } : { limit };
29673
+ const { data } = await this.http.get('/api/v1/invitations', { params: Object.assign(Object.assign({}, params), { options }) });
29674
+ return data;
29675
+ }
29676
+ }
29677
+
29678
+ class InvitationsQueryStreamController extends QueryStreamController {
29679
+ constructor(query, cacheKey, notifyChange, preparePayload) {
29680
+ super(query, cacheKey);
29681
+ this.notifyChange = notifyChange;
29682
+ this.preparePayload = preparePayload;
29683
+ }
29684
+ async saveToMainDB(response) {
29685
+ const processedPayload = await this.preparePayload(response);
29686
+ const client = getActiveClient();
29687
+ const cachedAt = client.cache && Date.now();
29688
+ if (client.cache) {
29689
+ ingestInCache(processedPayload, { cachedAt });
29690
+ }
29691
+ }
29692
+ appendToQueryStream(response, direction, refresh = false) {
29693
+ var _a, _b;
29694
+ if (refresh) {
29695
+ pushToCache(this.cacheKey, {
29696
+ data: response.invitations.map(getResolver('invitation')),
29697
+ });
29698
+ }
29699
+ else {
29700
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
29701
+ const invitations = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
29702
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [
29703
+ ...new Set([...invitations, ...response.invitations.map(getResolver('invitation'))]),
29704
+ ] }));
29705
+ }
29706
+ }
29707
+ reactor(action) {
29708
+ return (invitations) => {
29709
+ var _a;
29710
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
29711
+ if (!collection)
29712
+ return;
29713
+ if (action === InvitationActionsEnum.OnLocalInvitationUpdated) {
29714
+ const isExist = collection.data.find(id => id === invitations[0].invitationId);
29715
+ if (!isExist)
29716
+ return;
29717
+ }
29718
+ if (action === InvitationActionsEnum.OnLocalInvitationCreated) {
29719
+ collection.data = [
29720
+ ...new Set([
29721
+ ...invitations.map(invitation => invitation.invitationId),
29722
+ ...collection.data,
29723
+ ]),
29724
+ ];
29725
+ }
29726
+ if (action === InvitationActionsEnum.OnLocalInvitationDeleted) {
29727
+ collection.data = collection.data.filter(id => id !== invitations[0].invitationId);
29728
+ }
29729
+ pushToCache(this.cacheKey, collection);
29730
+ this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
29731
+ };
29732
+ }
29733
+ subscribeRTE(createSubscriber) {
29734
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
29735
+ }
29736
+ }
29737
+
29738
+ /**
29739
+ * ```js
29740
+ * import { onLocalInvitationCreated } from '@amityco/ts-sdk'
29741
+ * const dispose = onLocalInvitationCreated(data => {
29742
+ * // ...
29743
+ * })
29744
+ * ```
29745
+ *
29746
+ * Fired when an {@link Amity.InvitationPayload} has been created
29747
+ *
29748
+ * @param callback The function to call when the event was fired
29749
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
29750
+ *
29751
+ * @category Invitation Events
29752
+ */
29753
+ const onLocalInvitationCreated = (callback) => {
29754
+ const client = getActiveClient();
29755
+ const disposers = [
29756
+ createEventSubscriber(client, 'onLocalInvitationCreated', 'local.invitation.created', payload => callback(payload)),
29757
+ ];
29758
+ return () => {
29759
+ disposers.forEach(fn => fn());
29760
+ };
29761
+ };
29762
+
29763
+ /**
29764
+ * ```js
29765
+ * import { onLocalInvitationUpdated } from '@amityco/ts-sdk'
29766
+ * const dispose = onLocalInvitationUpdated(data => {
29767
+ * // ...
29768
+ * })
29769
+ * ```
29770
+ *
29771
+ * Fired when an {@link Amity.InvitationPayload} has been updated
29772
+ *
29773
+ * @param callback The function to call when the event was fired
29774
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
29775
+ *
29776
+ * @category Invitation Events
29777
+ */
29778
+ const onLocalInvitationUpdated = (callback) => {
29779
+ const client = getActiveClient();
29780
+ const disposers = [
29781
+ createEventSubscriber(client, 'onLocalInvitationUpdated', 'local.invitation.updated', payload => callback(payload)),
29782
+ ];
29783
+ return () => {
29784
+ disposers.forEach(fn => fn());
29785
+ };
29786
+ };
29787
+
29788
+ /**
29789
+ * ```js
29790
+ * import { onLocalInvitationCanceled } from '@amityco/ts-sdk'
29791
+ * const dispose = onLocalInvitationCanceled(data => {
29792
+ * // ...
29793
+ * })
29794
+ * ```
29795
+ *
29796
+ * Fired when an {@link Amity.InvitationPayload} has been deleted
29797
+ *
29798
+ * @param callback The function to call when the event was fired
29799
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
29800
+ *
29801
+ * @category Invitation Events
29802
+ */
29803
+ const onLocalInvitationCanceled = (callback) => {
29804
+ const client = getActiveClient();
29805
+ const disposers = [
29806
+ createEventSubscriber(client, 'onLocalInvitationCanceled', 'local.invitation.canceled', payload => callback(payload)),
29807
+ ];
29808
+ return () => {
29809
+ disposers.forEach(fn => fn());
29810
+ };
29811
+ };
29812
+
29813
+ class InvitationsLiveCollectionController extends LiveCollectionController {
29814
+ constructor(query, callback) {
29815
+ const queryStreamId = hash(query);
29816
+ const cacheKey = ['invitation', 'collection', queryStreamId];
29817
+ const paginationController = new InvitationsPaginationController(query);
29818
+ super(paginationController, queryStreamId, cacheKey, callback);
29819
+ this.query = query;
29820
+ this.queryStreamController = new InvitationsQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), prepareInvitationPayload);
29821
+ this.callback = callback.bind(this);
29822
+ this.loadPage({ initial: true });
29823
+ }
29824
+ setup() {
29825
+ var _a;
29826
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
29827
+ if (!collection) {
29828
+ pushToCache(this.cacheKey, {
29829
+ data: [],
29830
+ params: this.query,
29831
+ });
29832
+ }
29833
+ }
29834
+ async persistModel(queryPayload) {
29835
+ await this.queryStreamController.saveToMainDB(queryPayload);
29836
+ }
29837
+ persistQueryStream({ response, direction, refresh, }) {
29838
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
29839
+ }
29840
+ startSubscription() {
29841
+ return this.queryStreamController.subscribeRTE([
29842
+ {
29843
+ fn: onLocalInvitationCreated,
29844
+ action: InvitationActionsEnum.OnLocalInvitationCreated,
29845
+ },
29846
+ {
29847
+ fn: onLocalInvitationUpdated,
29848
+ action: InvitationActionsEnum.OnLocalInvitationUpdated,
29849
+ },
29850
+ {
29851
+ fn: onLocalInvitationCanceled,
29852
+ action: InvitationActionsEnum.OnLocalInvitationCanceled,
29853
+ },
29854
+ ]);
29855
+ }
29856
+ notifyChange({ origin, loading, error }) {
29857
+ var _a, _b;
29858
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
29859
+ if (!collection)
29860
+ return;
29861
+ const data = this.applyFilter((_b = collection.data
29862
+ .map(id => pullFromCache(['invitation', 'get', id]))
29863
+ .filter(isNonNullable)
29864
+ .map(({ data }) => invitationLinkedObject(data))) !== null && _b !== void 0 ? _b : []);
29865
+ if (!this.shouldNotify(data) && origin === 'event')
29866
+ return;
29867
+ this.callback({
29868
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
29869
+ data,
29870
+ hasNextPage: !!this.paginationController.getNextToken(),
29871
+ loading,
29872
+ error,
29873
+ });
29874
+ }
29875
+ applyFilter(data) {
29876
+ let invitations = data;
29877
+ if (this.query.targetId) {
29878
+ invitations = invitations.filter(invitation => invitation.targetId === this.query.targetId);
29879
+ }
29880
+ if (this.query.statuses) {
29881
+ invitations = invitations.filter(invitation => { var _a; return (_a = this.query.statuses) === null || _a === void 0 ? void 0 : _a.includes(invitation.status); });
29882
+ }
29883
+ if (this.query.targetType) {
29884
+ invitations = invitations.filter(invitation => invitation.targetType === this.query.targetType);
29885
+ }
29886
+ if (this.query.type) {
29887
+ invitations = invitations.filter(invitation => invitation.type === this.query.type);
29888
+ }
29889
+ const sortFn = (() => {
29890
+ switch (this.query.sortBy) {
29891
+ case 'firstCreated':
29892
+ return sortByFirstCreated;
29893
+ case 'lastCreated':
29894
+ return sortByLastCreated;
29895
+ default:
29896
+ return sortByLastCreated;
29897
+ }
29898
+ })();
29899
+ invitations = invitations.sort(sortFn);
29900
+ return invitations;
29901
+ }
29902
+ }
29903
+
29904
+ /**
29905
+ * Get invitations
29906
+ *
29907
+ * @param params the query parameters
29908
+ * @param callback the callback to be called when the invitations are updated
29909
+ * @returns invitations
29910
+ *
29911
+ * @category Invitation Live Collection
29912
+ *
29913
+ */
29914
+ const getInvitations$1 = (params, callback, config) => {
29915
+ const { log, cache } = getActiveClient();
29916
+ if (!cache) {
29917
+ console.log(ENABLE_CACHE_MESSAGE);
29918
+ }
29919
+ const timestamp = Date.now();
29920
+ log(`getInvitations: (tmpid: ${timestamp}) > listen`);
29921
+ const invitationsLiveCollection = new InvitationsLiveCollectionController(params, callback);
29922
+ const disposers = invitationsLiveCollection.startSubscription();
29923
+ const cacheKey = invitationsLiveCollection.getCacheKey();
29924
+ disposers.push(() => {
29925
+ dropFromCache(cacheKey);
29926
+ });
29927
+ return () => {
29928
+ log(`getInvitations (tmpid: ${timestamp}) > dispose`);
29929
+ disposers.forEach(fn => fn());
29930
+ };
29931
+ };
29932
+
29495
29933
  const communityLinkedObject = (community) => {
29496
29934
  return Object.assign(Object.assign({}, community), { get categories() {
29497
29935
  var _a;
@@ -44463,8 +44901,12 @@ const onRoomCoHostInviteCanceled = (callback) => {
44463
44901
  const onRoomParticipantJoined = (callback) => {
44464
44902
  const client = getActiveClient();
44465
44903
  const filter = (payload) => {
44466
- ingestInCache(payload);
44467
- callback(payload.rooms[0]);
44904
+ const { rooms, users } = payload;
44905
+ ingestInCache({ rooms, users });
44906
+ callback({
44907
+ room: roomLinkedObject(rooms[0]),
44908
+ actorInternalId: payload.eventActor.userInternalId,
44909
+ });
44468
44910
  };
44469
44911
  return createEventSubscriber(client, 'room/onRoomParticipantJoined', 'room.participantJoined', filter);
44470
44912
  };
@@ -44487,12 +44929,72 @@ const onRoomParticipantJoined = (callback) => {
44487
44929
  const onRoomParticipantLeft = (callback) => {
44488
44930
  const client = getActiveClient();
44489
44931
  const filter = (payload) => {
44490
- ingestInCache(payload);
44491
- callback(payload.rooms[0]);
44932
+ const { rooms, users } = payload;
44933
+ ingestInCache({ rooms, users });
44934
+ callback({
44935
+ room: roomLinkedObject(rooms[0]),
44936
+ actorInternalId: payload.eventActor.userInternalId,
44937
+ });
44492
44938
  };
44493
44939
  return createEventSubscriber(client, 'room/onRoomParticipantLeft', 'room.participantLeft', filter);
44494
44940
  };
44495
44941
 
44942
+ /**
44943
+ * ```js
44944
+ * import { onRoomParticipantStageLeft } from '@amityco/ts-sdk'
44945
+ * const dispose = onRoomParticipantStageLeft(room => {
44946
+ * // ...
44947
+ * })
44948
+ * ```
44949
+ *
44950
+ * Fired when a participant has left the stage of a {@link Amity.Room}
44951
+ *
44952
+ * @param callback The function to call when the event was fired
44953
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
44954
+ *
44955
+ * @category Room Events
44956
+ */
44957
+ const onRoomParticipantStageLeft = (callback) => {
44958
+ const client = getActiveClient();
44959
+ const filter = (payload) => {
44960
+ const { rooms, users } = payload;
44961
+ ingestInCache({ rooms, users });
44962
+ callback({
44963
+ room: roomLinkedObject(rooms[0]),
44964
+ actorInternalId: payload.eventActor.userInternalId,
44965
+ });
44966
+ };
44967
+ return createEventSubscriber(client, 'room/onRoomParticipantStageLeft', 'room.participantStageLeft', filter);
44968
+ };
44969
+
44970
+ /**
44971
+ * ```js
44972
+ * import { onRoomParticipantStageJoined } from '@amityco/ts-sdk'
44973
+ * const dispose = onRoomParticipantStageJoined(room => {
44974
+ * // ...
44975
+ * })
44976
+ * ```
44977
+ *
44978
+ * Fired when a participant has joined the stage of a {@link Amity.Room}
44979
+ *
44980
+ * @param callback The function to call when the event was fired
44981
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
44982
+ *
44983
+ * @category Room Events
44984
+ */
44985
+ const onRoomParticipantStageJoined = (callback) => {
44986
+ const client = getActiveClient();
44987
+ const filter = (payload) => {
44988
+ const { rooms, users } = payload;
44989
+ ingestInCache({ rooms, users });
44990
+ callback({
44991
+ room: roomLinkedObject(rooms[0]),
44992
+ actorInternalId: payload.eventActor.userInternalId,
44993
+ });
44994
+ };
44995
+ return createEventSubscriber(client, 'room/onRoomParticipantStageJoined', 'room.participantStageJoined', filter);
44996
+ };
44997
+
44496
44998
  /**
44497
44999
  * ```js
44498
45000
  * import { onRoomTerminated } from '@amityco/ts-sdk'
@@ -44631,8 +45133,12 @@ const onRoomStopped = (callback) => {
44631
45133
  const onRoomParticipantRemoved = (callback) => {
44632
45134
  const client = getActiveClient();
44633
45135
  const filter = (payload) => {
44634
- ingestInCache(payload);
44635
- callback(payload.rooms[0]);
45136
+ const { rooms, users } = payload;
45137
+ ingestInCache({ rooms, users });
45138
+ callback({
45139
+ room: roomLinkedObject(rooms[0]),
45140
+ actorInternalId: payload.eventActor.userInternalId,
45141
+ });
44636
45142
  };
44637
45143
  return createEventSubscriber(client, 'room/onRoomParticipantRemoved', 'room.participantRemoved', filter);
44638
45144
  };
@@ -44685,6 +45191,68 @@ const onRoomParticipantRemovedLocal = (callback) => {
44685
45191
  return createEventSubscriber(client, 'room/onRoomParticipantRemoved', 'local.room.participantRemoved', filter);
44686
45192
  };
44687
45193
 
45194
+ var EnumRoomActions;
45195
+ (function (EnumRoomActions) {
45196
+ EnumRoomActions["OnRoomCreated"] = "OnRoomCreated";
45197
+ EnumRoomActions["OnRoomUpdated"] = "OnRoomUpdated";
45198
+ EnumRoomActions["OnRoomDeleted"] = "OnRoomDeleted";
45199
+ EnumRoomActions["OnRoomStartBroadcasting"] = "OnRoomStartBroadcasting";
45200
+ EnumRoomActions["OnRoomEndBroadcasting"] = "OnRoomEndBroadcasting";
45201
+ EnumRoomActions["OnRoomParticipantJoined"] = "OnRoomParticipantJoined";
45202
+ EnumRoomActions["OnRoomParticipantLeft"] = "OnRoomParticipantLeft";
45203
+ })(EnumRoomActions || (EnumRoomActions = {}));
45204
+
45205
+ const convertToRoomEventPayload = (eventHandler) => (callback) => eventHandler((payload) => {
45206
+ callback(payload.room);
45207
+ });
45208
+ // TODO: confirm related events
45209
+ const getRoomSubscription = () => [
45210
+ {
45211
+ fn: onRoomStartBroadcasting,
45212
+ action: EnumRoomActions.OnRoomStartBroadcasting,
45213
+ },
45214
+ {
45215
+ fn: onRoomEndBroadcasting,
45216
+ action: EnumRoomActions.OnRoomEndBroadcasting,
45217
+ },
45218
+ {
45219
+ fn: onRoomRecordedAvailable,
45220
+ action: EnumRoomActions.OnRoomUpdated,
45221
+ },
45222
+ {
45223
+ fn: onRoomWaitingReconnect,
45224
+ action: EnumRoomActions.OnRoomUpdated,
45225
+ },
45226
+ {
45227
+ fn: onRoomTerminated,
45228
+ action: EnumRoomActions.OnRoomUpdated,
45229
+ },
45230
+ {
45231
+ fn: convertToRoomEventPayload(onRoomParticipantJoined),
45232
+ action: EnumRoomActions.OnRoomUpdated,
45233
+ },
45234
+ {
45235
+ fn: convertToRoomEventPayload(onRoomParticipantLeft),
45236
+ action: EnumRoomActions.OnRoomUpdated,
45237
+ },
45238
+ {
45239
+ fn: convertToRoomEventPayload(onRoomParticipantRemoved),
45240
+ action: EnumRoomActions.OnRoomUpdated,
45241
+ },
45242
+ {
45243
+ fn: onRoomParticipantRemovedLocal,
45244
+ action: EnumRoomActions.OnRoomUpdated,
45245
+ },
45246
+ {
45247
+ fn: convertToRoomEventPayload(onRoomParticipantStageJoined),
45248
+ action: EnumRoomActions.OnRoomUpdated,
45249
+ },
45250
+ {
45251
+ fn: convertEventPayload(onRoomCoHostInviteAccepted, 'targetId', 'room'),
45252
+ action: EnumRoomActions.OnRoomUpdated,
45253
+ },
45254
+ ];
45255
+
44688
45256
  const getRoom = (roomId, callback) => {
44689
45257
  // TODO: add callbackDataSelector if there are linked object fields
44690
45258
  return liveObject(roomId, callback, '_id', getRoomById, [
@@ -44693,10 +45261,11 @@ const getRoom = (roomId, callback) => {
44693
45261
  onRoomWaitingReconnect,
44694
45262
  onRoomTerminated,
44695
45263
  onRoomRecordedAvailable,
44696
- onRoomParticipantJoined,
44697
- onRoomParticipantLeft,
44698
- onRoomParticipantRemoved,
45264
+ convertToRoomEventPayload(onRoomParticipantJoined),
45265
+ convertToRoomEventPayload(onRoomParticipantLeft),
45266
+ convertToRoomEventPayload(onRoomParticipantRemoved),
44699
45267
  onRoomParticipantRemovedLocal,
45268
+ convertToRoomEventPayload(onRoomParticipantStageJoined),
44700
45269
  convertEventPayload(onRoomCoHostInviteAccepted, 'targetId', 'room'),
44701
45270
  ], {
44702
45271
  callbackDataSelector: (data) => {
@@ -44721,17 +45290,6 @@ class RoomPaginationController extends PaginationController {
44721
45290
  }
44722
45291
  }
44723
45292
 
44724
- var EnumRoomActions;
44725
- (function (EnumRoomActions) {
44726
- EnumRoomActions["OnRoomCreated"] = "OnRoomCreated";
44727
- EnumRoomActions["OnRoomUpdated"] = "OnRoomUpdated";
44728
- EnumRoomActions["OnRoomDeleted"] = "OnRoomDeleted";
44729
- EnumRoomActions["OnRoomStartBroadcasting"] = "OnRoomStartBroadcasting";
44730
- EnumRoomActions["OnRoomEndBroadcasting"] = "OnRoomEndBroadcasting";
44731
- EnumRoomActions["OnRoomParticipantJoined"] = "OnRoomParticipantJoined";
44732
- EnumRoomActions["OnRoomParticipantLeft"] = "OnRoomParticipantLeft";
44733
- })(EnumRoomActions || (EnumRoomActions = {}));
44734
-
44735
45293
  class RoomQueryStreamController extends QueryStreamController {
44736
45294
  constructor(query, cacheKey, notifyChange, preparePayload) {
44737
45295
  super(query, cacheKey);
@@ -44780,22 +45338,6 @@ class RoomQueryStreamController extends QueryStreamController {
44780
45338
  }
44781
45339
  }
44782
45340
 
44783
- // TODO: confirm related events
44784
- const getRoomSubscription = () => [
44785
- {
44786
- fn: onRoomStartBroadcasting,
44787
- action: EnumRoomActions.OnRoomStartBroadcasting,
44788
- },
44789
- {
44790
- fn: onRoomEndBroadcasting,
44791
- action: EnumRoomActions.OnRoomEndBroadcasting,
44792
- },
44793
- {
44794
- fn: onRoomRecordedAvailable,
44795
- action: EnumRoomActions.OnRoomUpdated,
44796
- },
44797
- ];
44798
-
44799
45341
  class RoomLiveCollectionController extends LiveCollectionController {
44800
45342
  constructor(query, callback) {
44801
45343
  const queryStreamId = hash(query);
@@ -44834,7 +45376,7 @@ class RoomLiveCollectionController extends LiveCollectionController {
44834
45376
  const data = this.applyFilter((_b = collection.data
44835
45377
  .map(id => pullFromCache(['room', 'get', id]))
44836
45378
  .filter(isNonNullable)
44837
- .map(({ data }) => data)) !== null && _b !== void 0 ? _b : []).map(room => room); // Since Room is same as InternalRoom, no transformation needed
45379
+ .map(({ data }) => data)) !== null && _b !== void 0 ? _b : []).map(roomLinkedObject);
44838
45380
  if (!this.shouldNotify(data) && origin === 'event')
44839
45381
  return;
44840
45382
  this.callback({
@@ -44927,6 +45469,10 @@ var index$b = /*#__PURE__*/Object.freeze({
44927
45469
  getRecordedUrl: getRecordedUrl,
44928
45470
  removeParticipant: removeParticipant,
44929
45471
  leaveRoom: leaveRoom,
45472
+ AmityRoomAnalytics: AmityRoomAnalytics,
45473
+ WatchSessionStorage: WatchSessionStorage,
45474
+ getWatchSessionStorage: getWatchSessionStorage,
45475
+ syncWatchSessions: syncWatchSessions,
44930
45476
  onRoomStartBroadcasting: onRoomStartBroadcasting,
44931
45477
  onRoomWaitingReconnect: onRoomWaitingReconnect,
44932
45478
  onRoomEndBroadcasting: onRoomEndBroadcasting,
@@ -44937,6 +45483,8 @@ var index$b = /*#__PURE__*/Object.freeze({
44937
45483
  onRoomCoHostInviteCanceled: onRoomCoHostInviteCanceled,
44938
45484
  onRoomParticipantJoined: onRoomParticipantJoined,
44939
45485
  onRoomParticipantLeft: onRoomParticipantLeft,
45486
+ onRoomParticipantStageLeft: onRoomParticipantStageLeft,
45487
+ onRoomParticipantStageJoined: onRoomParticipantStageJoined,
44940
45488
  onRoomTerminated: onRoomTerminated,
44941
45489
  onRoomCreated: onRoomCreated,
44942
45490
  onRoomUpdated: onRoomUpdated,
@@ -46440,85 +46988,6 @@ var index$7 = /*#__PURE__*/Object.freeze({
46440
46988
  getPoll: getPoll
46441
46989
  });
46442
46990
 
46443
- 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-----";
46444
- /*
46445
- * The crypto algorithm used for importing key and signing string
46446
- */
46447
- const ALGORITHM = {
46448
- name: 'RSASSA-PKCS1-v1_5',
46449
- hash: { name: 'SHA-256' },
46450
- };
46451
- /*
46452
- * IMPORTANT!
46453
- * If you are recieving key from other platforms use an online tool to convert
46454
- * the PKCS1 to PKCS8. For instance the key from Android SDK is of the format
46455
- * PKCS1.
46456
- *
46457
- * If recieving from the platform, verify if it's already in the expected
46458
- * format. Otherwise the crypto.subtle.importKey will throw a DOMException
46459
- */
46460
- const PRIVATE_KEY_SIGNATURE = 'pkcs8';
46461
- /*
46462
- * Ensure that the private key in the .env follows this format
46463
- */
46464
- const PEM_HEADER = '-----BEGIN PRIVATE KEY-----';
46465
- const PEM_FOOTER = '-----END PRIVATE KEY-----';
46466
- /*
46467
- * The crypto.subtle.sign function returns an ArrayBuffer whereas the server
46468
- * expects a base64 string. This util helps facilitate that process
46469
- */
46470
- function base64FromArrayBuffer(buffer) {
46471
- const uint8Array = new Uint8Array(buffer);
46472
- let binary = '';
46473
- uint8Array.forEach(byte => {
46474
- binary += String.fromCharCode(byte);
46475
- });
46476
- return btoa(binary);
46477
- }
46478
- /*
46479
- * Convert a string into an ArrayBuffer
46480
- * from https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
46481
- *
46482
- * Solely used by the importPrivateKey method
46483
- */
46484
- function str2ab(str) {
46485
- const buf = new ArrayBuffer(str.length);
46486
- const bufView = new Uint8Array(buf);
46487
- for (let i = 0, strLen = str.length; i < strLen; i += 1) {
46488
- bufView[i] = str.charCodeAt(i);
46489
- }
46490
- return buf;
46491
- }
46492
- function importPrivateKey(pem) {
46493
- // fetch the part of the PEM string between header and footer
46494
- const pemContents = pem.substring(PEM_HEADER.length, pem.length - PEM_FOOTER.length);
46495
- /*
46496
- * base64 decode the string to get the binary data
46497
- */
46498
- const binaryDerString = atob(pemContents);
46499
- // convert from a binary string to an ArrayBuffer
46500
- const binaryDer = str2ab(binaryDerString);
46501
- return crypto.subtle.importKey(PRIVATE_KEY_SIGNATURE, binaryDer, ALGORITHM, false, ['sign']);
46502
- }
46503
- async function createSignature({ timestamp, streams, }) {
46504
- const dataStr = streams
46505
- .map(item => Object.keys(item)
46506
- .sort()
46507
- .map(key => `${key}=${item[key]}`)
46508
- .join('&'))
46509
- .join(';');
46510
- /*
46511
- * nonceStr needs to be unique for each request
46512
- */
46513
- const nonceStr = uuid$1.v4();
46514
- const signStr = `nonceStr=${nonceStr}&timestamp=${timestamp}&data=${dataStr}==`;
46515
- const encoder = new TextEncoder();
46516
- const data = encoder.encode(signStr);
46517
- const key = await importPrivateKey(privateKey);
46518
- const sign = await crypto.subtle.sign(ALGORITHM, key, data);
46519
- return { signature: base64FromArrayBuffer(sign), nonceStr };
46520
- }
46521
-
46522
46991
  async function syncUsage({ bufferCurrentUsage, getActiveStreams, updateUsage, dispose, }) {
46523
46992
  const streams = bufferCurrentUsage();
46524
46993
  if (!streams.length)
@@ -48740,24 +49209,30 @@ var index$2 = /*#__PURE__*/Object.freeze({
48740
49209
  * @param referenceType should be 'post'
48741
49210
  * @param reactionName that is the reaction name
48742
49211
  * @param streamId stream id
49212
+ * @param roomId room id
48743
49213
  * @returns a success boolean if the reaction was added
48744
49214
  *
48745
49215
  * @category Live Reaction API
48746
49216
  * @async
48747
49217
  */
48748
- const createReaction = async ({ referenceId, referenceType, reactionName, roomId, }) => {
49218
+ const createReaction = async ({ referenceId, referenceType, reactionName, streamId, roomId, }) => {
48749
49219
  const client = getActiveClient();
48750
49220
  client.log('live_reaction/createReaction', {
48751
49221
  referenceId,
48752
49222
  referenceType,
48753
49223
  reactionName,
49224
+ streamId,
49225
+ roomId,
48754
49226
  });
49227
+ if (!streamId && !roomId)
49228
+ throw new ASCError('You have to specify either streamId or roomId', 800110 /* Amity.ClientError.INVALID_PARAMETERS */, "error" /* Amity.ErrorLevel.ERROR */);
48755
49229
  const reactionSynceEngine = ReactionSyncEngine.getInstance();
48756
49230
  const reaction = {
48757
49231
  reactionName,
48758
49232
  referencePublicId: referenceId,
48759
49233
  referenceType,
48760
49234
  roomId,
49235
+ streamId,
48761
49236
  occurredAt: new Date().toISOString(),
48762
49237
  };
48763
49238
  reactionSynceEngine.createLiveReaction(reaction);
@@ -48947,15 +49422,32 @@ const updateEvent = async (eventId, bundle) => {
48947
49422
  const getEvent$1 = async (eventId) => {
48948
49423
  const client = getActiveClient();
48949
49424
  client.log('event/getEvent', eventId);
48950
- const { data: payload } = await client.http.get(`/api/v1/events/${eventId}`);
48951
- const data = prepareEventPayload(payload);
48952
- const cachedAt = client.cache && Date.now();
48953
- if (client.cache)
48954
- ingestInCache(data, { cachedAt });
48955
- return {
48956
- data: data.events.find(event => event.eventId === eventId),
48957
- cachedAt,
48958
- };
49425
+ try {
49426
+ const { data: payload } = await client.http.get(`/api/v1/events/${eventId}`);
49427
+ const data = prepareEventPayload(payload);
49428
+ const cachedAt = client.cache && Date.now();
49429
+ if (client.cache)
49430
+ ingestInCache(data, { cachedAt });
49431
+ return {
49432
+ data: data.events.find(event => event.eventId === eventId),
49433
+ cachedAt,
49434
+ };
49435
+ }
49436
+ catch (error) {
49437
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
49438
+ const event = getEvent$1.locally(eventId);
49439
+ if (!event)
49440
+ throw error;
49441
+ const deletedEvent = Object.assign(Object.assign({}, event === null || event === void 0 ? void 0 : event.data), { isDeleted: true });
49442
+ upsertInCache(['event', 'get', eventId], deletedEvent);
49443
+ const cachedAt = client.cache && Date.now();
49444
+ return {
49445
+ data: deletedEvent,
49446
+ cachedAt,
49447
+ };
49448
+ }
49449
+ throw error;
49450
+ }
48959
49451
  };
48960
49452
  /* end_public_function */
48961
49453
  /**