@amityco/ts-sdk-react-native 6.33.1 → 6.34.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 (40) hide show
  1. package/dist/@types/core/payload.d.ts +8 -0
  2. package/dist/@types/core/payload.d.ts.map +1 -1
  3. package/dist/@types/domains/community.d.ts +16 -0
  4. package/dist/@types/domains/community.d.ts.map +1 -1
  5. package/dist/communityRepository/constants/index.d.ts +6 -0
  6. package/dist/communityRepository/constants/index.d.ts.map +1 -0
  7. package/dist/communityRepository/index.d.ts +1 -0
  8. package/dist/communityRepository/index.d.ts.map +1 -1
  9. package/dist/communityRepository/observers/index.d.ts +1 -0
  10. package/dist/communityRepository/observers/index.d.ts.map +1 -1
  11. package/dist/communityRepository/observers/semanticSearch/SemanticSearchCommunityLiveCollectionController.d.ts +14 -0
  12. package/dist/communityRepository/observers/semanticSearch/SemanticSearchCommunityLiveCollectionController.d.ts.map +1 -0
  13. package/dist/communityRepository/observers/semanticSearch/SemanticSearchCommunityPaginationController.d.ts +10 -0
  14. package/dist/communityRepository/observers/semanticSearch/SemanticSearchCommunityPaginationController.d.ts.map +1 -0
  15. package/dist/communityRepository/observers/semanticSearch/SemanticSearchCommunityQueryStreamController.d.ts +16 -0
  16. package/dist/communityRepository/observers/semanticSearch/SemanticSearchCommunityQueryStreamController.d.ts.map +1 -0
  17. package/dist/communityRepository/observers/semanticSearch/enums.d.ts +6 -0
  18. package/dist/communityRepository/observers/semanticSearch/enums.d.ts.map +1 -0
  19. package/dist/communityRepository/observers/semanticSearch/utils.d.ts +3 -0
  20. package/dist/communityRepository/observers/semanticSearch/utils.d.ts.map +1 -0
  21. package/dist/communityRepository/observers/semanticSearchCommunities.d.ts +10 -0
  22. package/dist/communityRepository/observers/semanticSearchCommunities.d.ts.map +1 -0
  23. package/dist/communityRepository/utils/payload.d.ts +1 -0
  24. package/dist/communityRepository/utils/payload.d.ts.map +1 -1
  25. package/dist/index.cjs.js +223 -21
  26. package/dist/index.esm.js +223 -21
  27. package/dist/index.umd.js +3 -3
  28. package/package.json +1 -1
  29. package/src/@types/core/payload.ts +7 -0
  30. package/src/@types/domains/community.ts +24 -0
  31. package/src/communityRepository/constants/index.ts +5 -0
  32. package/src/communityRepository/index.ts +1 -0
  33. package/src/communityRepository/observers/index.ts +2 -0
  34. package/src/communityRepository/observers/semanticSearch/SemanticSearchCommunityLiveCollectionController.ts +164 -0
  35. package/src/communityRepository/observers/semanticSearch/SemanticSearchCommunityPaginationController.ts +36 -0
  36. package/src/communityRepository/observers/semanticSearch/SemanticSearchCommunityQueryStreamController.ts +86 -0
  37. package/src/communityRepository/observers/semanticSearch/enums.ts +5 -0
  38. package/src/communityRepository/observers/semanticSearch/utils.ts +16 -0
  39. package/src/communityRepository/observers/semanticSearchCommunities.ts +42 -0
  40. package/src/communityRepository/utils/payload.ts +11 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amityco/ts-sdk-react-native",
3
- "version": "6.33.1",
3
+ "version": "6.34.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[];
@@ -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
  }
@@ -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
+ };