@amityco/ts-sdk 6.33.1 → 6.33.2-3719e72.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 (58) hide show
  1. package/.env +26 -26
  2. package/dist/@types/core/payload.d.ts +8 -0
  3. package/dist/@types/core/payload.d.ts.map +1 -1
  4. package/dist/@types/domains/client.d.ts +2 -2
  5. package/dist/@types/domains/client.d.ts.map +1 -1
  6. package/dist/@types/domains/community.d.ts +16 -0
  7. package/dist/@types/domains/community.d.ts.map +1 -1
  8. package/dist/client/api/createClient.d.ts.map +1 -1
  9. package/dist/client/api/isConnected.d.ts.map +1 -1
  10. package/dist/client/api/logout.d.ts.map +1 -1
  11. package/dist/client/utils/modifyMqttConnection.d.ts.map +1 -1
  12. package/dist/communityRepository/constants/index.d.ts +6 -0
  13. package/dist/communityRepository/constants/index.d.ts.map +1 -0
  14. package/dist/communityRepository/index.d.ts +1 -0
  15. package/dist/communityRepository/index.d.ts.map +1 -1
  16. package/dist/communityRepository/observers/index.d.ts +1 -0
  17. package/dist/communityRepository/observers/index.d.ts.map +1 -1
  18. package/dist/communityRepository/observers/semanticSearch/SemanticSearchCommunityLiveCollectionController.d.ts +14 -0
  19. package/dist/communityRepository/observers/semanticSearch/SemanticSearchCommunityLiveCollectionController.d.ts.map +1 -0
  20. package/dist/communityRepository/observers/semanticSearch/SemanticSearchCommunityPaginationController.d.ts +10 -0
  21. package/dist/communityRepository/observers/semanticSearch/SemanticSearchCommunityPaginationController.d.ts.map +1 -0
  22. package/dist/communityRepository/observers/semanticSearch/SemanticSearchCommunityQueryStreamController.d.ts +16 -0
  23. package/dist/communityRepository/observers/semanticSearch/SemanticSearchCommunityQueryStreamController.d.ts.map +1 -0
  24. package/dist/communityRepository/observers/semanticSearch/enums.d.ts +6 -0
  25. package/dist/communityRepository/observers/semanticSearch/enums.d.ts.map +1 -0
  26. package/dist/communityRepository/observers/semanticSearch/utils.d.ts +3 -0
  27. package/dist/communityRepository/observers/semanticSearch/utils.d.ts.map +1 -0
  28. package/dist/communityRepository/observers/semanticSearchCommunities.d.ts +10 -0
  29. package/dist/communityRepository/observers/semanticSearchCommunities.d.ts.map +1 -0
  30. package/dist/communityRepository/utils/payload.d.ts +1 -0
  31. package/dist/communityRepository/utils/payload.d.ts.map +1 -1
  32. package/dist/core/subscription.d.ts.map +1 -1
  33. package/dist/index.cjs.js +250 -32
  34. package/dist/index.esm.js +250 -32
  35. package/dist/index.umd.js +4 -4
  36. package/package.json +1 -1
  37. package/src/@types/core/payload.ts +7 -0
  38. package/src/@types/domains/client.ts +2 -2
  39. package/src/@types/domains/community.ts +24 -0
  40. package/src/client/api/createClient.ts +12 -2
  41. package/src/client/api/isConnected.ts +4 -1
  42. package/src/client/api/login.ts +1 -1
  43. package/src/client/api/logout.ts +6 -5
  44. package/src/client/utils/modifyMqttConnection.ts +2 -0
  45. package/src/client/utils/setClientToken.ts +1 -1
  46. package/src/communityRepository/constants/index.ts +5 -0
  47. package/src/communityRepository/index.ts +1 -0
  48. package/src/communityRepository/observers/index.ts +2 -0
  49. package/src/communityRepository/observers/semanticSearch/SemanticSearchCommunityLiveCollectionController.ts +164 -0
  50. package/src/communityRepository/observers/semanticSearch/SemanticSearchCommunityPaginationController.ts +36 -0
  51. package/src/communityRepository/observers/semanticSearch/SemanticSearchCommunityQueryStreamController.ts +86 -0
  52. package/src/communityRepository/observers/semanticSearch/enums.ts +5 -0
  53. package/src/communityRepository/observers/semanticSearch/utils.ts +16 -0
  54. package/src/communityRepository/observers/semanticSearchCommunities.ts +42 -0
  55. package/src/communityRepository/utils/payload.ts +11 -0
  56. package/src/core/events.ts +2 -2
  57. package/src/core/subscription.ts +2 -0
  58. package/src/core/transports/ws.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amityco/ts-sdk",
3
- "version": "6.33.1",
3
+ "version": "6.33.2-3719e72.0",
4
4
  "license": "CC-BY-ND-4.0",
5
5
  "author": "amity.co <developers@amity.co> (https://amity.co)",
6
6
  "description": "Amity Social Cloud Typescript SDK",
@@ -25,6 +25,7 @@ declare global {
25
25
  following: Amity.FollowingsPayload;
26
26
  blockUser: Amity.BlockedUserPayload;
27
27
  semanticSearchPost: Amity.SemanticSearchPostPayload;
28
+ semanticSearchCommunity: Amity.SemanticSearchCommunityPayload;
28
29
  };
29
30
 
30
31
  type UserPayload = {
@@ -336,6 +337,12 @@ declare global {
336
337
  polls: Amity.InternalPoll[];
337
338
  };
338
339
 
340
+ type SemanticSearchCommunityPayload = Amity.CommunityPayload & {
341
+ searchResult: { communityId: string; score: number }[];
342
+ };
343
+
344
+ type ProcessedSemanticSearchCommunityPayload = Amity.ProcessedCommunityPayload;
345
+
339
346
  type StoryBasePayload = {
340
347
  comments: Amity.InternalComment[];
341
348
  files: Amity.File[];
@@ -36,8 +36,8 @@ declare global {
36
36
 
37
37
  log: Logger;
38
38
  http: AxiosInstance;
39
- mqtt: Amity.MqttClient;
40
- ws: SocketIOClient.Socket;
39
+ mqtt?: Amity.MqttClient;
40
+ ws?: SocketIOClient.Socket;
41
41
  emitter: Emitter<Amity.Events>;
42
42
 
43
43
  hasPermission: (permission: string) => Amity.PermissionChecker;
@@ -1,3 +1,5 @@
1
+ import { AmityCommunityMemberStatusFilter } from '~/communityRepository/constants';
2
+
1
3
  export const CommunityPostSettings = Object.freeze({
2
4
  ONLY_ADMIN_CAN_POST: 'ONLY_ADMIN_CAN_POST',
3
5
  ADMIN_REVIEW_POST_REQUIRED: 'ADMIN_REVIEW_POST_REQUIRED',
@@ -193,5 +195,27 @@ declare global {
193
195
  Amity.Community['communityId'],
194
196
  Pick<QuerySearchCommunityMembers, 'page'>
195
197
  >;
198
+
199
+ type QuerySemanticSearchCommunity = {
200
+ query: string;
201
+ categoryIds?: string[];
202
+ filter?: AmityCommunityMemberStatusFilter;
203
+ options?: {
204
+ limit?: number;
205
+ token?: string;
206
+ };
207
+ tags?: string[];
208
+ };
209
+
210
+ type SemanticSearchCommunityLiveCollection = Amity.LiveCollectionParams<
211
+ Omit<QuerySemanticSearchCommunity, 'page' | 'filter' | 'options'>
212
+ > & {
213
+ communityMembershipStatus?: AmityCommunityMemberStatusFilter;
214
+ };
215
+
216
+ type SemanticSearchCommunityLiveCollectionCache = Amity.LiveCollectionCache<
217
+ Amity.Community['communityId'], // communityId:score
218
+ QuerySemanticSearchCommunity
219
+ >;
196
220
  }
197
221
  }
@@ -64,8 +64,18 @@ export const createClient = (
64
64
  const mqttEndpoint = apiEndpoint?.mqtt ?? computeUrl('mqtt', apiRegion);
65
65
 
66
66
  const http = createHttpTransport(httpEndpoint);
67
- const ws = createWebsocketTransport(httpEndpoint);
68
- const mqtt = createMqttTransport(mqttEndpoint);
67
+
68
+ const isGoogleBotOrInspectionTool =
69
+ typeof navigator !== 'undefined' &&
70
+ (/Googlebot/.test(navigator.userAgent) || /Google-InspectionTool/.test(navigator.userAgent));
71
+
72
+ let ws;
73
+ let mqtt;
74
+
75
+ if (!isGoogleBotOrInspectionTool) {
76
+ ws = createWebsocketTransport(httpEndpoint);
77
+ mqtt = createMqttTransport(mqttEndpoint);
78
+ }
69
79
 
70
80
  const emitter = createEventEmitter();
71
81
 
@@ -16,9 +16,12 @@ export const isConnected = (): boolean => {
16
16
  const client = getActiveClient();
17
17
  client.log('client/api/isConnected', client);
18
18
 
19
+ // if client is connected to ws, it means client is connected. If ws is undefined, it means ws is not used.
20
+ const isWsConnected = (client.ws && client.ws.connected) || !!client.ws;
21
+
19
22
  return !!(
20
23
  client.userId &&
21
24
  String(client.http.defaults.headers.common?.Authorization)?.length &&
22
- client.ws.connected
25
+ isWsConnected
23
26
  );
24
27
  };
@@ -125,7 +125,7 @@ export const login = async (
125
125
  // wire websocket events to our event emitter
126
126
  proxyWebsocketEvents(client.ws, client.emitter);
127
127
 
128
- client.ws.open();
128
+ client.ws?.open();
129
129
 
130
130
  client.userId = user.userId;
131
131
 
@@ -22,11 +22,11 @@ export const logout = async (): Promise<boolean> => {
22
22
 
23
23
  client.log('client/api/disconnectClient');
24
24
 
25
- if (client.mqtt.connected) {
25
+ if (client.mqtt && client.mqtt.connected) {
26
26
  client.mqtt.disconnect();
27
27
  }
28
28
 
29
- if (client.ws.connected) {
29
+ if (client.ws && client.ws.connected) {
30
30
  client.ws.disconnect();
31
31
  }
32
32
 
@@ -47,8 +47,8 @@ export const logout = async (): Promise<boolean> => {
47
47
 
48
48
  client.emitter.all.clear();
49
49
  // FIXME: it removes listener in ws.ts, it breaks global ban event
50
- client.ws.removeAllListeners();
51
- client.mqtt.removeAllListeners();
50
+ client.ws?.removeAllListeners();
51
+ client.mqtt?.removeAllListeners();
52
52
  client.userId = undefined;
53
53
  client.token = undefined;
54
54
 
@@ -58,7 +58,8 @@ export const logout = async (): Promise<boolean> => {
58
58
  isGlobalBanned: false,
59
59
  isUserDeleted: false,
60
60
  };
61
- client.ws.io.opts.query = { token: '' };
61
+
62
+ if (client.ws) client.ws.io.opts.query = { token: '' };
62
63
 
63
64
  if (typeof document !== 'undefined') {
64
65
  document.cookie = '_ascSession=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
@@ -7,6 +7,8 @@ let mqttUserId: string;
7
7
 
8
8
  export async function modifyMqttConnection() {
9
9
  const { mqtt, emitter, token } = getActiveClient();
10
+ if (!mqtt) return;
11
+
10
12
  const accessToken = token?.accessToken ?? '';
11
13
 
12
14
  const user = getActiveUser();
@@ -31,7 +31,7 @@ export const setClientToken = async (params: Parameters<typeof getToken>[0]) =>
31
31
  };
32
32
 
33
33
  // manually setup the token for ws transport
34
- client.ws.io.opts.query = { token: accessToken };
34
+ if (client.ws) client.ws.io.opts.query = { token: accessToken };
35
35
 
36
36
  client.token = { accessToken, issuedAt, expiresAt };
37
37
 
@@ -0,0 +1,5 @@
1
+ export const enum AmityCommunityMemberStatusFilter {
2
+ ALL = 'all',
3
+ MEMBER = 'member',
4
+ NOT_MEMBER = 'notMember',
5
+ }
@@ -1,6 +1,7 @@
1
1
  export * from './api';
2
2
  export * from './events';
3
3
  export * from './observers';
4
+ export * from './constants';
4
5
 
5
6
  export * as Moderation from './communityModeration';
6
7
  export * as Membership from './communityMembership';
@@ -5,3 +5,5 @@ export * from './getCommunities';
5
5
  export * from './getCommunity';
6
6
  export * from './getTrendingCommunities';
7
7
  export * from './getRecommendedCommunities';
8
+
9
+ export * from './semanticSearchCommunities';
@@ -0,0 +1,164 @@
1
+ import hash from 'object-hash';
2
+ import { pullFromCache, pushToCache } from '~/cache/api';
3
+ import { SemanticSearchCommunityPaginationController } from './SemanticSearchCommunityPaginationController';
4
+ import { SemanticSearchCommunityQueryStreamController } from './SemanticSearchCommunityQueryStreamController';
5
+ import { LiveCollectionController } from '~/core/liveCollection/LiveCollectionController';
6
+ import {
7
+ onCommunityCreated,
8
+ onCommunityDeleted,
9
+ onCommunityUpdated,
10
+ } from '~/communityRepository/events';
11
+
12
+ import {
13
+ onCommunityJoined,
14
+ onCommunityLeft,
15
+ onLocalCommunityJoined,
16
+ onLocalCommunityLeft,
17
+ onCommunityUserChanged,
18
+ } from '~/communityRepository/communityMembership';
19
+
20
+ import { isNonNullable } from '~/utils';
21
+ import { EnumCommunityActions } from './enums';
22
+ import { prepareSemanticSearchCommunityPayload } from '~/communityRepository/utils/payload';
23
+
24
+ import { getActiveClient } from '~/client';
25
+ import { EnumCommunityMemberActions } from '~/communityRepository/communityMembership/observers/getMembers/enums';
26
+ import { filterByCommunityMembership } from '~/core/query';
27
+
28
+ export class SemanticSearchCommunityLiveCollectionController extends LiveCollectionController<
29
+ 'semanticSearchCommunity',
30
+ Amity.SemanticSearchCommunityLiveCollection,
31
+ Amity.Community,
32
+ SemanticSearchCommunityPaginationController
33
+ > {
34
+ private queryStreamController: SemanticSearchCommunityQueryStreamController;
35
+
36
+ private query: Amity.SemanticSearchCommunityLiveCollection;
37
+
38
+ constructor(
39
+ query: Amity.SemanticSearchCommunityLiveCollection,
40
+ callback: Amity.LiveCollectionCallback<Amity.Community>,
41
+ ) {
42
+ const queryStreamId = hash(query);
43
+ const cacheKey = ['community', 'collection', queryStreamId];
44
+ const paginationController = new SemanticSearchCommunityPaginationController(query);
45
+
46
+ super(paginationController, queryStreamId, cacheKey, callback);
47
+
48
+ this.query = query;
49
+
50
+ this.queryStreamController = new SemanticSearchCommunityQueryStreamController(
51
+ this.query,
52
+ this.cacheKey,
53
+ this.notifyChange.bind(this),
54
+ prepareSemanticSearchCommunityPayload,
55
+ );
56
+
57
+ this.callback = callback.bind(this);
58
+ this.loadPage({ initial: true });
59
+ }
60
+
61
+ protected setup() {
62
+ const collection = pullFromCache<Amity.SemanticSearchCommunityLiveCollectionCache>(
63
+ this.cacheKey,
64
+ )?.data;
65
+ if (!collection) {
66
+ pushToCache(this.cacheKey, {
67
+ data: [],
68
+ params: {},
69
+ });
70
+ }
71
+ }
72
+
73
+ protected async persistModel(
74
+ queryPayload: Amity.SemanticSearchCommunityPayload & Amity.Pagination,
75
+ ) {
76
+ await this.queryStreamController.saveToMainDB(queryPayload);
77
+ }
78
+
79
+ protected persistQueryStream({
80
+ response,
81
+ direction,
82
+ refresh,
83
+ }: Amity.LiveCollectionPersistQueryStreamParams<'semanticSearchCommunity'>) {
84
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
85
+ }
86
+
87
+ startSubscription() {
88
+ return this.queryStreamController.subscribeRTE([
89
+ { fn: onCommunityCreated, action: EnumCommunityActions.OnCommunityCreated },
90
+ { fn: onCommunityDeleted, action: EnumCommunityActions.OnCommunityDeleted },
91
+ { fn: onCommunityUpdated, action: EnumCommunityActions.OnCommunityUpdated },
92
+ { fn: onCommunityJoined, action: EnumCommunityMemberActions.OnCommunityJoined },
93
+ { fn: onCommunityLeft, action: EnumCommunityMemberActions.OnCommunityLeft },
94
+ { fn: onCommunityUserChanged, action: EnumCommunityMemberActions.OnMemberCountChanged },
95
+ { fn: onLocalCommunityJoined, action: EnumCommunityMemberActions.OnCommunityJoined },
96
+ { fn: onLocalCommunityLeft, action: EnumCommunityMemberActions.OnCommunityLeft },
97
+ ]);
98
+ }
99
+
100
+ notifyChange({ origin, loading, error }: Amity.LiveCollectionNotifyParams) {
101
+ const collection = pullFromCache<Amity.SemanticSearchCommunityLiveCollectionCache>(
102
+ this.cacheKey,
103
+ )?.data;
104
+ if (!collection) return;
105
+
106
+ const data = this.applyFilter(
107
+ collection.data
108
+ .map(communityIdWithScore => {
109
+ const [communityId, score] = communityIdWithScore.split(':');
110
+ return {
111
+ communityId,
112
+ score: parseFloat(score),
113
+ };
114
+ })
115
+ .sort((a, b) => b.score - a.score)
116
+ .map(
117
+ ({ communityId }) => pullFromCache<Amity.Community>(['community', 'get', communityId])!,
118
+ )
119
+ .filter(isNonNullable)
120
+ .map(({ data }) => data) ?? [],
121
+ );
122
+
123
+ if (!this.shouldNotify(data) && origin === 'event') return;
124
+
125
+ this.callback({
126
+ onNextPage: () => this.loadPage({ direction: Amity.LiveCollectionPageDirection.NEXT }),
127
+ data,
128
+ hasNextPage: !!this.paginationController.getNextToken(),
129
+ loading,
130
+ error,
131
+ });
132
+ }
133
+
134
+ applyFilter(data: Amity.Community[]) {
135
+ const { userId } = getActiveClient();
136
+
137
+ let communities = data;
138
+
139
+ if (this.query.categoryIds) {
140
+ communities = communities.filter(c =>
141
+ c.categoryIds?.some((id: string) => {
142
+ if (!this.query.categoryIds) return true;
143
+ if (this.query.categoryIds.length === 0) return true;
144
+
145
+ return this.query.categoryIds.includes(id);
146
+ }),
147
+ );
148
+ }
149
+
150
+ if (this.query.tags) {
151
+ communities = communities.filter(c => c.tags?.some(t => this.query.tags?.includes(t)));
152
+ }
153
+
154
+ if (this.query.communityMembershipStatus && userId) {
155
+ communities = filterByCommunityMembership(
156
+ communities,
157
+ this.query.communityMembershipStatus,
158
+ userId,
159
+ );
160
+ }
161
+
162
+ return communities;
163
+ }
164
+ }
@@ -0,0 +1,36 @@
1
+ import { AmityCommunityMemberStatusFilter } from '~/communityRepository/constants';
2
+ import { PaginationController } from '~/core/liveCollection/PaginationController';
3
+ import { COLLECTION_DEFAULT_PAGINATION_LIMIT } from '~/utils/constants';
4
+
5
+ export class SemanticSearchCommunityPaginationController extends PaginationController<
6
+ 'semanticSearchCommunity',
7
+ Amity.SemanticSearchCommunityLiveCollection
8
+ > {
9
+ async getRequest(
10
+ queryParams: Amity.SemanticSearchCommunityLiveCollection,
11
+ token: string | undefined,
12
+ ) {
13
+ const {
14
+ limit = COLLECTION_DEFAULT_PAGINATION_LIMIT,
15
+ communityMembershipStatus,
16
+ ...params
17
+ } = queryParams;
18
+
19
+ const baseOptions = {
20
+ type: queryParams.limit ? 'pagination' : undefined,
21
+ };
22
+
23
+ const options = token ? { ...baseOptions, token } : { ...baseOptions, limit };
24
+
25
+ const { data: queryResponse } = await this.http.get<
26
+ Amity.SemanticSearchCommunityPayload & Amity.Pagination
27
+ >(`/api/v1/semantic-search/communities`, {
28
+ params: {
29
+ ...params,
30
+ filter: communityMembershipStatus ?? AmityCommunityMemberStatusFilter.ALL,
31
+ options,
32
+ },
33
+ });
34
+ return queryResponse;
35
+ }
36
+ }
@@ -0,0 +1,86 @@
1
+ import { QueryStreamController } from '~/core/liveCollection/QueryStreamController';
2
+ import { pullFromCache, pushToCache } from '~/cache/api';
3
+ import { ingestInCache } from '~/cache/api/ingestInCache';
4
+ import { getActiveClient } from '~/client';
5
+ // TODO: move emum to be the share value
6
+ import { EnumCommunityActions } from './enums';
7
+ import { EnumCommunityMemberActions } from '~/communityRepository/communityMembership/observers/getMembers/enums';
8
+ import { prepareSemanticCommunitiesReferenceId } from './utils';
9
+
10
+ export class SemanticSearchCommunityQueryStreamController extends QueryStreamController<
11
+ Amity.SemanticSearchCommunityPayload,
12
+ Amity.SemanticSearchCommunityLiveCollection
13
+ > {
14
+ private notifyChange: (params: Amity.LiveCollectionNotifyParams) => void;
15
+
16
+ private preparePayload: (
17
+ response: Amity.SemanticSearchCommunityPayload,
18
+ ) => Amity.ProcessedSemanticSearchCommunityPayload;
19
+
20
+ constructor(
21
+ query: Amity.SemanticSearchCommunityLiveCollection,
22
+ cacheKey: string[],
23
+ notifyChange: (params: Amity.LiveCollectionNotifyParams) => void,
24
+ preparePayload: (
25
+ response: Amity.SemanticSearchCommunityPayload,
26
+ ) => Amity.ProcessedSemanticSearchCommunityPayload,
27
+ ) {
28
+ super(query, cacheKey);
29
+ this.notifyChange = notifyChange;
30
+ this.preparePayload = preparePayload;
31
+ }
32
+
33
+ async saveToMainDB(response: Amity.SemanticSearchCommunityPayload) {
34
+ const processedPayload = this.preparePayload(response);
35
+
36
+ const client = getActiveClient();
37
+ const cachedAt = client.cache && Date.now();
38
+
39
+ if (client.cache) {
40
+ ingestInCache(processedPayload, { cachedAt });
41
+ }
42
+ }
43
+
44
+ appendToQueryStream(
45
+ response: Amity.SemanticSearchCommunityPayload & Partial<Amity.Pagination>,
46
+ direction: Amity.LiveCollectionPageDirection,
47
+ refresh = false,
48
+ ) {
49
+ if (refresh) {
50
+ pushToCache(this.cacheKey, {
51
+ data: prepareSemanticCommunitiesReferenceId(response),
52
+ });
53
+ } else {
54
+ const collection = pullFromCache<Amity.CommunityLiveCollectionCache>(this.cacheKey)?.data;
55
+
56
+ const communities = collection?.data ?? [];
57
+
58
+ pushToCache(this.cacheKey, {
59
+ ...collection,
60
+ data: [...new Set([...communities, ...prepareSemanticCommunitiesReferenceId(response)])],
61
+ });
62
+ }
63
+ }
64
+
65
+ reactor(action: EnumCommunityActions | EnumCommunityMemberActions) {
66
+ return (community: Amity.Community) => {
67
+ const collection = pullFromCache<Amity.CommunityLiveCollectionCache>(this.cacheKey)?.data;
68
+ if (!collection) return;
69
+
70
+ collection.data = [...new Set([community.communityId, ...collection.data])];
71
+
72
+ pushToCache(this.cacheKey, collection);
73
+ this.notifyChange({ origin: Amity.LiveDataOrigin.EVENT, loading: false });
74
+ };
75
+ //
76
+ }
77
+
78
+ subscribeRTE(
79
+ createSubscriber: {
80
+ fn: (reactor: (community: Amity.Community) => void) => Amity.Unsubscriber;
81
+ action: EnumCommunityActions | EnumCommunityMemberActions;
82
+ }[],
83
+ ) {
84
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
85
+ }
86
+ }
@@ -0,0 +1,5 @@
1
+ export enum EnumCommunityActions {
2
+ OnCommunityCreated = 'onCommunityCreated',
3
+ OnCommunityDeleted = 'onCommunityDeleted',
4
+ OnCommunityUpdated = 'onCommunityUpdated',
5
+ }
@@ -0,0 +1,16 @@
1
+ export function prepareSemanticCommunitiesReferenceId(
2
+ response: Amity.SemanticSearchCommunityPayload,
3
+ ) {
4
+ return response.communities.map(community => {
5
+ const score = response.searchResult.find(
6
+ result => result.communityId === community.communityId,
7
+ )!;
8
+ return `${community.communityId}:${score}`;
9
+ });
10
+ }
11
+
12
+ export function getCommunityIdsFromCache(cacheData?: string[]) {
13
+ return (cacheData ?? []).map(communityIdWithScore => {
14
+ return communityIdWithScore.split(':')[0];
15
+ });
16
+ }
@@ -0,0 +1,42 @@
1
+ import { getActiveClient } from '~/client/api';
2
+ import { dropFromCache } from '~/cache/api';
3
+ import { ENABLE_CACHE_MESSAGE } from '~/utils/constants';
4
+ import { SemanticSearchCommunityLiveCollectionController } from './semanticSearch/SemanticSearchCommunityLiveCollectionController';
5
+
6
+ /**
7
+ * search posts by semantic search
8
+ *
9
+ * @returns the associated pinned post(s)
10
+ *
11
+ * @category Posts Live Collection
12
+ *
13
+ */
14
+ export const semanticSearchCommunities = (
15
+ params: Amity.LiveCollectionParams<Amity.SemanticSearchCommunityLiveCollection>,
16
+ callback: Amity.LiveCollectionCallback<Amity.Community>,
17
+ config?: Amity.LiveCollectionConfig,
18
+ ) => {
19
+ const { log, cache } = getActiveClient();
20
+
21
+ if (!cache) {
22
+ console.log(ENABLE_CACHE_MESSAGE);
23
+ }
24
+
25
+ const timestamp = Date.now();
26
+ log(`semanticSearchCommunities(tmpid: ${timestamp}) > listen`);
27
+
28
+ const semanticSearchPostLiveCollection = new SemanticSearchCommunityLiveCollectionController(
29
+ params,
30
+ callback,
31
+ );
32
+ const disposers = semanticSearchPostLiveCollection.startSubscription();
33
+
34
+ const cacheKey = semanticSearchPostLiveCollection.getCacheKey();
35
+
36
+ disposers.push(() => dropFromCache(cacheKey));
37
+
38
+ return () => {
39
+ log(`semanticSearchCommunities(tmpid: ${timestamp}) > dispose`);
40
+ disposers.forEach(fn => fn());
41
+ };
42
+ };
@@ -101,3 +101,14 @@ export const prepareCommunityRequest = <
101
101
  typeof storySetting?.enableComment === 'boolean' ? storySetting.enableComment : true,
102
102
  };
103
103
  };
104
+
105
+ export const prepareSemanticSearchCommunityPayload = ({
106
+ searchResult,
107
+ ...communityPayload
108
+ }: Amity.SemanticSearchCommunityPayload): Amity.ProcessedSemanticSearchCommunityPayload => {
109
+ const processedCommunityPayload = prepareCommunityPayload(communityPayload);
110
+
111
+ return {
112
+ ...processedCommunityPayload,
113
+ };
114
+ };
@@ -50,7 +50,7 @@ export const createEventEmitter = () => {
50
50
  */
51
51
  export const proxyWebsocketEvents = (ws: Amity.Client['ws'], emitter: Amity.Client['emitter']) => {
52
52
  WS_EVENTS.forEach(event => {
53
- ws.on(event, (param: Amity.Events[typeof event]) => {
53
+ ws?.on(event, (param: Amity.Events[typeof event]) => {
54
54
  emitter.emit(event, param);
55
55
  });
56
56
  });
@@ -61,7 +61,7 @@ export const proxyMqttEvents = (
61
61
  emitter: Amity.Client['emitter'],
62
62
  ) => {
63
63
  MQTT_EVENTS.forEach(event => {
64
- mqttClient.on(event, (...params: any[]) => {
64
+ mqttClient?.on(event, (...params: any[]) => {
65
65
  emitter.emit(event, params.length === 1 ? params[0] : params);
66
66
  });
67
67
  });
@@ -162,6 +162,8 @@ export function subscribeTopic(
162
162
  callback?: Amity.Listener<ASCError | void>,
163
163
  ): Amity.Unsubscriber {
164
164
  const { mqtt } = getActiveClient();
165
+ if (!mqtt) return () => null;
166
+
165
167
  modifyMqttConnection();
166
168
 
167
169
  return mqtt.subscribe(topic, callback);
@@ -47,7 +47,7 @@ export const synchronousWSCall = async <T>(
47
47
  const { ws } = client;
48
48
 
49
49
  const value = await new Promise<T | undefined>((resolve, reject) => {
50
- ws.emit(event, data, (response: Amity.Response<T>) => {
50
+ ws?.emit(event, data, (response: Amity.Response<T>) => {
51
51
  try {
52
52
  resolve(unwrapPayload(response));
53
53
  } catch (error) {