@amityco/ts-sdk 6.4.6-e12bdf9.0 → 6.5.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 (125) hide show
  1. package/dist/@types/core/events.d.ts +4 -4
  2. package/dist/@types/core/events.d.ts.map +1 -1
  3. package/dist/@types/core/model.d.ts +3 -1
  4. package/dist/@types/core/model.d.ts.map +1 -1
  5. package/dist/@types/core/payload.d.ts +1 -1
  6. package/dist/@types/core/payload.d.ts.map +1 -1
  7. package/dist/@types/domains/post.d.ts +1 -1
  8. package/dist/@types/domains/post.d.ts.map +1 -1
  9. package/dist/@types/domains/reaction.d.ts +4 -5
  10. package/dist/@types/domains/reaction.d.ts.map +1 -1
  11. package/dist/channelRepsitory/channelMembership/observers/getMembers.d.ts +1 -0
  12. package/dist/channelRepsitory/channelMembership/observers/getMembers.d.ts.map +1 -1
  13. package/dist/client/observers/getTotalUnreadCount.d.ts.map +1 -1
  14. package/dist/client/utils/markerSyncEngine.d.ts.map +1 -1
  15. package/dist/commentRepository/observers/getComment.d.ts +2 -2
  16. package/dist/communityRepository/api/getCommunity.d.ts +4 -4
  17. package/dist/communityRepository/api/getRecommendedCommunities.d.ts +4 -19
  18. package/dist/communityRepository/api/getRecommendedCommunities.d.ts.map +1 -1
  19. package/dist/communityRepository/api/getTopTrendingCommunities.d.ts +5 -2
  20. package/dist/communityRepository/api/getTopTrendingCommunities.d.ts.map +1 -1
  21. package/dist/communityRepository/api/getTrendingCommunities.d.ts +17 -0
  22. package/dist/communityRepository/api/getTrendingCommunities.d.ts.map +1 -0
  23. package/dist/communityRepository/api/index.d.ts +0 -1
  24. package/dist/communityRepository/api/index.d.ts.map +1 -1
  25. package/dist/communityRepository/api/test/getTrendingCommunities.test.d.ts +2 -0
  26. package/dist/communityRepository/api/test/getTrendingCommunities.test.d.ts.map +1 -0
  27. package/dist/communityRepository/communityMembership/observers/getMembers.d.ts +1 -0
  28. package/dist/communityRepository/communityMembership/observers/getMembers.d.ts.map +1 -1
  29. package/dist/communityRepository/observers/getCommunities.d.ts +2 -2
  30. package/dist/communityRepository/observers/getCommunity.d.ts +2 -2
  31. package/dist/communityRepository/observers/getRecommendedCommunities.d.ts +20 -0
  32. package/dist/communityRepository/observers/getRecommendedCommunities.d.ts.map +1 -0
  33. package/dist/communityRepository/observers/getTrendingCommunities.d.ts +20 -0
  34. package/dist/communityRepository/observers/getTrendingCommunities.d.ts.map +1 -0
  35. package/dist/communityRepository/observers/index.d.ts +2 -0
  36. package/dist/communityRepository/observers/index.d.ts.map +1 -1
  37. package/dist/communityRepository/utils/communityQueryFilter.d.ts +2 -0
  38. package/dist/communityRepository/utils/communityQueryFilter.d.ts.map +1 -0
  39. package/dist/core/model/idResolvers.d.ts.map +1 -1
  40. package/dist/core/model/identifyModel.d.ts.map +1 -1
  41. package/dist/index.cjs.js +554 -237
  42. package/dist/index.esm.js +554 -237
  43. package/dist/index.umd.js +4 -4
  44. package/dist/pollRepository/api/index.d.ts +0 -1
  45. package/dist/pollRepository/api/index.d.ts.map +1 -1
  46. package/dist/pollRepository/observers/getPoll.d.ts +21 -0
  47. package/dist/pollRepository/observers/getPoll.d.ts.map +1 -0
  48. package/dist/pollRepository/observers/index.d.ts +1 -0
  49. package/dist/pollRepository/observers/index.d.ts.map +1 -1
  50. package/dist/postRepository/observers/getPost.d.ts +2 -2
  51. package/dist/reactionRepository/api/addReaction.d.ts +2 -2
  52. package/dist/reactionRepository/api/addReaction.d.ts.map +1 -1
  53. package/dist/reactionRepository/api/queryReactions.d.ts +2 -2
  54. package/dist/reactionRepository/api/queryReactions.d.ts.map +1 -1
  55. package/dist/reactionRepository/api/queryReactor.d.ts +19 -0
  56. package/dist/reactionRepository/api/queryReactor.d.ts.map +1 -0
  57. package/dist/reactionRepository/api/removeReaction.d.ts +2 -2
  58. package/dist/reactionRepository/api/removeReaction.d.ts.map +1 -1
  59. package/dist/reactionRepository/observers/getReactions.d.ts +3 -3
  60. package/dist/reactionRepository/observers/getReactions.d.ts.map +1 -1
  61. package/dist/streamRepository/observers/getStreamById.d.ts +19 -2
  62. package/dist/streamRepository/observers/getStreamById.d.ts.map +1 -1
  63. package/dist/streamRepository/observers/getStreams.d.ts.map +1 -1
  64. package/dist/streamRepository/observers/tests/getStreamById.test.d.ts +2 -0
  65. package/dist/streamRepository/observers/tests/getStreamById.test.d.ts.map +1 -0
  66. package/dist/userRepository/observers/getUsers.d.ts +1 -0
  67. package/dist/userRepository/observers/getUsers.d.ts.map +1 -1
  68. package/dist/utils/tests/dummy/reaction.d.ts +1 -1
  69. package/dist/utils/tests/dummy/reaction.d.ts.map +1 -1
  70. package/dist/utils/tests/dummy/stream.d.ts +22 -0
  71. package/dist/utils/tests/dummy/stream.d.ts.map +1 -1
  72. package/package.json +1 -1
  73. package/src/@types/core/events.ts +4 -4
  74. package/src/@types/core/model.ts +3 -1
  75. package/src/@types/core/payload.ts +1 -1
  76. package/src/@types/domains/post.ts +1 -1
  77. package/src/@types/domains/reaction.ts +8 -9
  78. package/src/categoryRepository/api/queryCategories.ts +1 -1
  79. package/src/channelRepsitory/channelMembership/observers/getMembers.ts +47 -39
  80. package/src/channelRepsitory/channelMembership/observers/tests/getMembers.test.ts +82 -5
  81. package/src/client/observers/getTotalUnreadCount.ts +1 -7
  82. package/src/client/observers/tests/getTotalUnreadCount.test.ts +3 -10
  83. package/src/client/utils/markerSyncEngine.ts +13 -2
  84. package/src/commentRepository/events/onCommentReactionAdded.ts +1 -1
  85. package/src/commentRepository/events/onCommentReactionRemoved.ts +1 -1
  86. package/src/commentRepository/observers/getComment.ts +2 -2
  87. package/src/commentRepository/observers/tests/getComment.test.ts +1 -3
  88. package/src/communityRepository/api/getCommunity.ts +4 -4
  89. package/src/communityRepository/api/getRecommendedCommunities.ts +7 -48
  90. package/src/communityRepository/api/getTopTrendingCommunities.ts +5 -2
  91. package/src/communityRepository/api/getTrendingCommunities.ts +50 -0
  92. package/src/communityRepository/api/index.ts +1 -1
  93. package/src/communityRepository/api/test/getTrendingCommunities.test.ts +102 -0
  94. package/src/communityRepository/communityMembership/observers/getMembers.ts +31 -23
  95. package/src/communityRepository/communityMembership/observers/tests/getMembers.test.ts +80 -2
  96. package/src/communityRepository/observers/getCommunities.ts +2 -2
  97. package/src/communityRepository/observers/getCommunity.ts +2 -2
  98. package/src/communityRepository/observers/getRecommendedCommunities.ts +130 -0
  99. package/src/communityRepository/observers/getTrendingCommunities.ts +130 -0
  100. package/src/communityRepository/observers/index.ts +2 -0
  101. package/src/communityRepository/utils/communityQueryFilter.ts +55 -0
  102. package/src/core/model/idResolvers.ts +2 -1
  103. package/src/core/model/identifyModel.ts +5 -4
  104. package/src/pollRepository/api/index.ts +0 -2
  105. package/src/pollRepository/observers/getPoll.ts +33 -0
  106. package/src/pollRepository/observers/index.ts +1 -0
  107. package/src/pollRepository/observers/observePoll.ts +2 -2
  108. package/src/postRepository/events/tests/onPostReactionAdded.test.ts +6 -5
  109. package/src/postRepository/events/tests/onPostReactionRemoved.test.ts +5 -4
  110. package/src/postRepository/observers/getPost.ts +2 -2
  111. package/src/postRepository/observers/getPosts.ts +1 -1
  112. package/src/postRepository/observers/tests/getPost.test.ts +1 -3
  113. package/src/postRepository/observers/tests/getPosts.test.ts +1 -5
  114. package/src/reactionRepository/api/addReaction.ts +2 -2
  115. package/src/reactionRepository/api/queryReactions.ts +2 -2
  116. package/src/reactionRepository/api/queryReactor.ts +31 -0
  117. package/src/reactionRepository/api/removeReaction.ts +2 -2
  118. package/src/reactionRepository/observers/getReactions.ts +6 -8
  119. package/src/streamRepository/observers/getStreamById.ts +35 -1
  120. package/src/streamRepository/observers/getStreams.ts +6 -5
  121. package/src/streamRepository/observers/tests/getStreamById.test.ts +44 -0
  122. package/src/userRepository/observers/getUsers.ts +32 -24
  123. package/src/userRepository/observers/tests/getUsers.test.ts +46 -1
  124. package/src/utils/tests/dummy/reaction.ts +6 -10
  125. package/src/utils/tests/dummy/stream.ts +47 -0
@@ -33,15 +33,9 @@ export const getTotalUnreadCount = (
33
33
  Amity.ErrorLevel.ERROR,
34
34
  );
35
35
 
36
- const callbackDataSelector = (data: Amity.UserMarker) => data?.unreadCount ?? 0;
37
-
38
- // based on the mobile specs, unreadCount will not trigger observer when userMarker
39
- // is re-fetched, so apply this filter to ensure the behavior is the same.
40
- const callbackFilter = (newModel: Amity.UserMarker, oldModel: Amity.UserMarker) =>
41
- newModel?.unreadCount !== oldModel?.unreadCount;
36
+ const callbackDataSelector = (data: Amity.UserMarker | undefined) => data?.unreadCount ?? 0;
42
37
 
43
38
  return liveObject(userId, callback, 'userId', getUserMarker, [onUserMarkerFetched], {
44
39
  callbackDataSelector,
45
- callbackFilter,
46
40
  });
47
41
  };
@@ -59,7 +59,7 @@ describe('getTotalUnreadCount', () => {
59
59
 
60
60
  await pause();
61
61
 
62
- expect(callback).toHaveBeenCalledTimes(1);
62
+ expect(callback).toHaveBeenCalledTimes(2);
63
63
  // on initial, expect 0 unread count
64
64
  expect(callback).toHaveBeenLastCalledWith({
65
65
  origin: 'server',
@@ -72,7 +72,7 @@ describe('getTotalUnreadCount', () => {
72
72
 
73
73
  await pause();
74
74
 
75
- expect(callback).toHaveBeenCalledTimes(2);
75
+ expect(callback).toHaveBeenCalledTimes(3);
76
76
  expect(callback).toHaveBeenLastCalledWith(expected);
77
77
  });
78
78
 
@@ -89,12 +89,6 @@ describe('getTotalUnreadCount', () => {
89
89
  await pause();
90
90
 
91
91
  // initial callback
92
- expect(callback).toHaveBeenCalledTimes(1);
93
-
94
- client.emitter.emit('local.userMarker.fetched', refreshUpdateTime(eventPayload));
95
-
96
- await pause();
97
-
98
92
  expect(callback).toHaveBeenCalledTimes(2);
99
93
 
100
94
  // emit duplicated event
@@ -102,7 +96,6 @@ describe('getTotalUnreadCount', () => {
102
96
 
103
97
  await pause();
104
98
 
105
- // should not re-trigger
106
- expect(callback).toHaveBeenCalledTimes(2);
99
+ expect(callback).toHaveBeenCalledTimes(3);
107
100
  });
108
101
  });
@@ -4,7 +4,7 @@ import {
4
4
  onChannelJoined,
5
5
  onChannelLeft,
6
6
  } from '~/channelRepsitory';
7
- import { onUserMarkerSync } from '~/marker/events/onUserMarkerSync'
7
+ import { onUserMarkerSync } from '~/marker/events/onUserMarkerSync';
8
8
  import { setIntervalTask } from '~/utils/timer';
9
9
  import { getUserMarker } from '~/marker/api';
10
10
  import { onFeedMarkerUpdated } from '~/marker/events';
@@ -15,6 +15,7 @@ import { isUnreadCountSupport } from '~/subChannelRepository/utils';
15
15
  import { markerSync } from '../api';
16
16
 
17
17
  const SYNC_TRIGGER_INTERVAL_TIME = 2000;
18
+ const ON_SUB_CHANNEL_DELETE_SYNC_TRIGGER_DELAY = 2000;
18
19
 
19
20
  let clearSyncTrigger: Amity.Unsubscriber | undefined;
20
21
  let disposers: (() => void)[] = [];
@@ -138,7 +139,17 @@ const registerEventListeners = () => {
138
139
  onChannelJoined(() => events.push(Amity.MarkerSyncEvent.CHANNEL_JOINED)),
139
140
  onChannelLeft(() => events.push(Amity.MarkerSyncEvent.CHANNEL_LEFT)),
140
141
  onSubChannelCreated(() => events.push(Amity.MarkerSyncEvent.SUB_CHANNEL_CREATED)),
141
- onSubChannelDeleted(() => events.push(Amity.MarkerSyncEvent.SUBCHANNEL_IS_DELETED)),
142
+ onSubChannelDeleted(() =>
143
+ /*
144
+ workaround: when receiving the event for sub-channel deletion,
145
+ before triggering marker update, the SDK will have to add a 2-second delay.
146
+ so that the unread count is calculated correctly.
147
+ */
148
+ setTimeout(
149
+ () => events.push(Amity.MarkerSyncEvent.SUBCHANNEL_IS_DELETED),
150
+ ON_SUB_CHANNEL_DELETE_SYNC_TRIGGER_DELAY,
151
+ ),
152
+ ),
142
153
  onFeedMarkerUpdated(() => events.push(Amity.MarkerSyncEvent.MARKER_UPDATED)),
143
154
  onUserMarkerSync(() => events.push(Amity.MarkerSyncEvent.MARKER_UPDATED)),
144
155
  );
@@ -24,7 +24,7 @@ export const onCommentReactionAdded = (
24
24
  ): Amity.Unsubscriber => {
25
25
  const client = getActiveClient();
26
26
 
27
- const filter = (payload: Amity.CommentPayload & { reactor: Amity.Reaction }) => {
27
+ const filter = (payload: Amity.CommentPayload & { reactor: Amity.Reactor }) => {
28
28
  if (!client.cache) {
29
29
  callback(payload.comments[0]);
30
30
  } else {
@@ -24,7 +24,7 @@ export const onCommentReactionRemoved = (
24
24
  ): Amity.Unsubscriber => {
25
25
  const client = getActiveClient();
26
26
 
27
- const filter = (payload: Amity.CommentPayload & { reactor: Amity.Reaction }) => {
27
+ const filter = (payload: Amity.CommentPayload & { reactor: Amity.Reactor }) => {
28
28
  if (!client.cache) {
29
29
  callback(payload.comments[0]);
30
30
  } else {
@@ -14,11 +14,11 @@ import {
14
14
  */
15
15
  /**
16
16
  * ```js
17
- * import { getComment } from '@amityco/ts-sdk';
17
+ * import { CommentRepository } from '@amityco/ts-sdk';
18
18
  *
19
19
  * let comment;
20
20
  *
21
- * const unsubscribe = getComment(commentId, response => {
21
+ * const unsub = CommentRepository.getComment(commentId, response => {
22
22
  * comment = response.data;
23
23
  * });
24
24
  * ```
@@ -75,12 +75,10 @@ describe('getComment', () => {
75
75
  data: { text: 'new-text' },
76
76
  updatedAt: getFutureDate(comment.updatedAt),
77
77
  };
78
- const reactor: Amity.Reaction = {
78
+ const reactor: Amity.Reactor = {
79
79
  createdAt: getFutureDate(comment.updatedAt),
80
80
  reactionId: 'like',
81
81
  reactionName: 'like',
82
- referenceId: comment.commentId,
83
- referenceType: 'comment',
84
82
  userId: user12.userId,
85
83
  };
86
84
  const callback = jest.fn();
@@ -7,8 +7,8 @@ import { prepareCommunityPayload } from '../utils';
7
7
 
8
8
  /**
9
9
  * ```js
10
- * import { getCommunity } from '@amityco/ts-sdk'
11
- * const community = await getCommunity('foobar')
10
+ * import { CommunityRepository } from '@amityco/ts-sdk'
11
+ * const community = await CommunityRepository.getCommunity('foobar')
12
12
  * ```
13
13
  *
14
14
  * Fetches a {@link Amity.Community} object
@@ -45,8 +45,8 @@ export const getCommunity = async (
45
45
 
46
46
  /**
47
47
  * ```js
48
- * import { getCommunity } from '@amityco/ts-sdk'
49
- * const community = getCommunity.locally('foobar')
48
+ * import { CommunityRepository } from '@amityco/ts-sdk'
49
+ * const community = CommunityRepository.getCommunity.locally('foobar')
50
50
  * ```
51
51
  *
52
52
  * Fetches a {@link Amity.Community} object from cache
@@ -5,14 +5,15 @@ import { pullFromCache, pushToCache } from '~/cache/api';
5
5
  import { ingestInCache } from '~/cache/api/ingestInCache';
6
6
 
7
7
  import { prepareCommunityPayload } from '../utils';
8
+ import { COLLECTION_DEFAULT_PAGINATION_LIMIT } from '~/utils/constants';
8
9
 
9
10
  /* begin_public_function
10
11
  id: community.query.recommended_communities
11
12
  */
12
13
  /**
13
14
  * ```js
14
- * import { getRecommendedCommunities } from '@amityco/ts-sdk'
15
- * const communities = await getRecommendedCommunities()
15
+ * import { CommunityRepository } from '@amityco/ts-sdk'
16
+ * const communities = await CommunityRepository.getRecommendedCommunities()
16
17
  * ```
17
18
  *
18
19
  * Gets a list of recommended {@link Amity.Community} objects
@@ -22,14 +23,15 @@ import { prepareCommunityPayload } from '../utils';
22
23
  *
23
24
  * @category Community API
24
25
  * @async
26
+ * @private
25
27
  */
26
28
  export const getRecommendedCommunities = async (
27
- query?: Partial<Amity.PageLimit>,
29
+ query?: Amity.PageLimit,
28
30
  ): Promise<Amity.Cached<Amity.Community[]>> => {
29
31
  const client = getActiveClient();
30
- client.log('channel/getRecommendedCommunities', query);
32
+ client.log('community/getRecommendedCommunities', query);
31
33
 
32
- const { limit = 5 } = query ?? {};
34
+ const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT } = query ?? {};
33
35
 
34
36
  // API-FIX: backend doesnt answer Amity.Response
35
37
  // const { data: payload } = await client.http.get<Amity.Response<CommunityPayload>>(
@@ -45,50 +47,7 @@ export const getRecommendedCommunities = async (
45
47
 
46
48
  if (client.cache) {
47
49
  ingestInCache(data, { cachedAt });
48
-
49
- const cacheKey = ['community', 'recommended', { params: { options: { limit } } }];
50
- pushToCache(cacheKey, { communities: communities.map(getResolver('community')) });
51
50
  }
52
51
 
53
52
  return { data: communities, cachedAt };
54
53
  };
55
- /* end_public_function */
56
-
57
- /**
58
- * ```js
59
- * import { getRecommendedCommunities } from '@amityco/ts-sdk'
60
- * const communities = getRecommendedCommunities.locally()
61
- * ```
62
- *
63
- * Gets a list of recommended {@link Amity.Community} objects from cache
64
- *
65
- * @param query The query parameters
66
- * @returns communities
67
- *
68
- * @category Community API
69
- */
70
- getRecommendedCommunities.locally = (
71
- query: Parameters<typeof getRecommendedCommunities>[0],
72
- ): Amity.Cached<Amity.Community[]> | undefined => {
73
- const client = getActiveClient();
74
- client.log('community/getRecommendedCommunities.locally', query);
75
-
76
- if (!client.cache) return;
77
-
78
- const { limit = 5 } = query ?? {};
79
-
80
- const queryKey = ['community', 'recommended', { params: { options: { limit } } }];
81
- const { data, cachedAt } =
82
- pullFromCache<{ communities: Pick<Amity.Community, 'communityId'>[] }>(queryKey) ?? {};
83
-
84
- if (!data?.communities.length) return;
85
-
86
- const communities: Amity.Community[] = data.communities
87
- .map(communityId => pullFromCache<Amity.Community>(['community', 'get', communityId])!)
88
- .filter(Boolean)
89
- .map(({ data }) => data);
90
-
91
- return communities.length === data?.communities?.length
92
- ? { data: communities, cachedAt }
93
- : undefined;
94
- };
@@ -10,9 +10,12 @@ import { prepareCommunityPayload } from '../utils';
10
10
  id: community.query.trending_communities
11
11
  */
12
12
  /**
13
+ * @deprecated This API renamed to `getTrendingCommunities()`.
14
+ * Please use getTrendingCommunities() instead.
15
+ *
13
16
  * ```js
14
- * import { getTopTrendingCommunities } from '@amityco/ts-sdk'
15
- * const trendingCommunities = await getTopTrendingCommunities()
17
+ * import { CommunityRepository } from '@amityco/ts-sdk'
18
+ * const trendingCommunities = await CommunityRepository.getTrendingCommunities()
16
19
  * ```
17
20
  *
18
21
  * Gets a list of top trending {@link Amity.Community} objects
@@ -0,0 +1,50 @@
1
+ import { getActiveClient } from '~/client/api';
2
+
3
+ import { getResolver } from '~/core/model';
4
+ import { pullFromCache, pushToCache } from '~/cache/api';
5
+ import { ingestInCache } from '~/cache/api/ingestInCache';
6
+
7
+ import { prepareCommunityPayload } from '../utils';
8
+ import { COLLECTION_DEFAULT_PAGINATION_LIMIT } from '~/utils/constants';
9
+
10
+ /**
11
+ * ```js
12
+ * import { CommunityRepository } from '@amityco/ts-sdk'
13
+ * const trendingCommunities = await CommunityRepository.getTrendingCommunities()
14
+ * ```
15
+ *
16
+ * Gets a list of top trending {@link Amity.Community} objects
17
+ *
18
+ * @param query The query parameters
19
+ * @returns A list of {@link Amity.Community} objects
20
+ *
21
+ * @category Community API
22
+ * @async
23
+ * @private
24
+ */
25
+ export const getTrendingCommunities = async (
26
+ query?: Amity.PageLimit,
27
+ ): Promise<Amity.Cached<Amity.Community[]>> => {
28
+ const client = getActiveClient();
29
+ client.log('community/getTrendingCommunities', query);
30
+
31
+ const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT } = query ?? {};
32
+
33
+ // API-FIX: backend doesnt answer Amity.Response
34
+ // const { data } = await client.http.get<Amity.Response<CommunityPayload>>(
35
+ const { data: payload } = await client.http.get<Amity.CommunityPayload>(
36
+ `/api/v3/communities/top-trending`,
37
+ { params: { options: { limit } } },
38
+ );
39
+
40
+ const data = prepareCommunityPayload(payload);
41
+ const { communities } = data;
42
+
43
+ const cachedAt = client.cache && Date.now();
44
+
45
+ if (client.cache) {
46
+ ingestInCache(data, { cachedAt });
47
+ }
48
+
49
+ return { data: communities, cachedAt };
50
+ };
@@ -7,5 +7,5 @@ export * from './deleteCommunity';
7
7
  export * from './joinCommunity';
8
8
  export * from './leaveCommunity';
9
9
 
10
+ // deprecated
10
11
  export * from './getTopTrendingCommunities';
11
- export * from './getRecommendedCommunities';
@@ -0,0 +1,102 @@
1
+ import { disableCache, enableCache, pullFromCache, pushToCache } from '~/cache/api';
2
+ import { client, community11, community21 } from '~/utils/tests';
3
+
4
+ import { getTrendingCommunities } from '../getTrendingCommunities';
5
+
6
+ const topTrendCommunities = [community11, community21];
7
+ const topTrendIds = topTrendCommunities.map(({ communityId }) => communityId);
8
+
9
+ const pagingToken = {
10
+ previous: 'eyJiZWZvcmUiOjU1LCJsYXN0IjoxMH0=',
11
+ next: 'eyJiZWZvcmUiOjU1LCJsYXN0IjoxMH0=',
12
+ };
13
+
14
+ const pagingCriteria = { limit: 10 };
15
+
16
+ const resolvedGetValue = {
17
+ data: {
18
+ communities: topTrendCommunities,
19
+ communityUsers: [community11, community21],
20
+ files: [],
21
+ users: [],
22
+ categories: [],
23
+ feeds: [],
24
+ paging: pagingToken,
25
+ },
26
+ };
27
+
28
+ describe('getTrendingCommunities', () => {
29
+ test('should return fetched top trend communities with correct paging', async () => {
30
+ client.http.get = jest.fn().mockResolvedValueOnce(resolvedGetValue);
31
+
32
+ await expect(getTrendingCommunities(pagingCriteria)).resolves.toEqual(
33
+ expect.objectContaining({ data: topTrendCommunities }),
34
+ );
35
+ });
36
+
37
+ test('should update cache after fetching top trend communities', async () => {
38
+ enableCache();
39
+ client.http.get = jest.fn().mockResolvedValue(resolvedGetValue);
40
+
41
+ await getTrendingCommunities(pagingCriteria);
42
+
43
+ const recieved = pullFromCache([
44
+ 'community',
45
+ 'top-trending',
46
+ { params: { options: pagingCriteria } },
47
+ ])?.data;
48
+
49
+ expect(recieved).toEqual({ communities: topTrendIds });
50
+
51
+ disableCache();
52
+ });
53
+
54
+ test('should throw an error if request fails', async () => {
55
+ client.http.get = jest.fn().mockRejectedValueOnce(new Error('error'));
56
+
57
+ await expect(getTrendingCommunities(pagingCriteria)).rejects.toThrow('error');
58
+ });
59
+ });
60
+
61
+ describe('getTopTrendingCommunities.locally', () => {
62
+ beforeEach(() => enableCache());
63
+ afterEach(() => disableCache());
64
+
65
+ test('should return cached top trend communities', () => {
66
+ topTrendCommunities.forEach(community =>
67
+ pushToCache(['community', 'get', community.communityId], community),
68
+ );
69
+
70
+ pushToCache(['community', 'top-trending', { params: { options: pagingCriteria } }], {
71
+ communities: topTrendIds,
72
+ });
73
+
74
+ expect(getTrendingCommunities.locally(pagingCriteria)?.data).toEqual(topTrendCommunities);
75
+ });
76
+
77
+ test('it should return undefined if top trend communities not in cache', () => {
78
+ topTrendCommunities.forEach(community =>
79
+ pushToCache(['community', 'get', community.communityId], community),
80
+ );
81
+
82
+ pushToCache(['community', 'top-trending', { params: { options: pagingCriteria } }], {
83
+ communities: topTrendIds,
84
+ });
85
+
86
+ expect(getTrendingCommunities.locally({ limit: -1 })).toBeUndefined();
87
+ });
88
+
89
+ test('should return undefined if cache not enabled', () => {
90
+ disableCache();
91
+
92
+ topTrendCommunities.forEach(community =>
93
+ pushToCache(['community', 'get', community.communityId], community),
94
+ );
95
+
96
+ pushToCache(['community', 'top-trending', { params: { options: pagingCriteria } }], {
97
+ communities: topTrendIds,
98
+ });
99
+
100
+ expect(getTrendingCommunities.locally(pagingCriteria)).toBeUndefined();
101
+ });
102
+ });
@@ -27,6 +27,35 @@ import {
27
27
  } from '../events';
28
28
  import { queryCommunityMembers } from '../api/queryCommunityMembers';
29
29
 
30
+ /*
31
+ * Exported for testing
32
+ * @hidden
33
+ */
34
+ export const applyFilter = <T extends Amity.Membership<'community'>>(
35
+ data: T[],
36
+ params: Amity.CommunityMemberLiveCollection,
37
+ ): T[] => {
38
+ let communityMembers = filterByPropIntersection(data, 'roles', params.roles);
39
+
40
+ if (params.membership) {
41
+ communityMembers = communityMembers.filter(({ communityMembership }) =>
42
+ // @ts-ignore
43
+ params.membership.includes(communityMembership),
44
+ );
45
+ }
46
+
47
+ if (params.search) {
48
+ communityMembers = filterBySearchTerm(communityMembers, params.search);
49
+ }
50
+
51
+ const sortBy = params.sortBy ? params.sortBy : 'lastCreated';
52
+ communityMembers = communityMembers.sort(
53
+ sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated,
54
+ );
55
+
56
+ return communityMembers;
57
+ };
58
+
30
59
  /* begin_public_function
31
60
  id: community.membership.query
32
61
  */
@@ -56,6 +85,7 @@ export const getMembers = (
56
85
  const { log, cache } = getActiveClient();
57
86
 
58
87
  if (!cache) {
88
+ // eslint-disable-next-line no-console
59
89
  console.log(ENABLE_CACHE_MESSAGE);
60
90
  }
61
91
 
@@ -70,28 +100,6 @@ export const getMembers = (
70
100
  const disposers: Amity.Unsubscriber[] = [];
71
101
  const cacheKey = ['communityUsers', 'collection', { communityId: params.communityId }];
72
102
 
73
- const applyFilter = <T extends Amity.Membership<'community'>>(data: T[]): T[] => {
74
- let communityMembers = filterByPropIntersection(data, 'roles', params.roles);
75
-
76
- if (params.membership) {
77
- communityMembers = communityMembers.filter(({ communityMembership }) =>
78
- // @ts-ignore
79
- params.membership.includes(communityMembership),
80
- );
81
- }
82
-
83
- if (params.search) {
84
- communityMembers = filterBySearchTerm(communityMembers, params.search);
85
- }
86
-
87
- const sortBy = params.sortBy ? params.sortBy : 'lastCreated';
88
- communityMembers = communityMembers.sort(
89
- sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated,
90
- );
91
-
92
- return communityMembers;
93
- };
94
-
95
103
  const responder = (data: Amity.CommunityMemberLiveCollectionCache, isEventModel = false) => {
96
104
  const communityMembers: Amity.Membership<'community'>[] =
97
105
  data.data
@@ -101,7 +109,7 @@ export const getMembers = (
101
109
 
102
110
  callback({
103
111
  onNextPage: onFetch,
104
- data: isEventModel ? applyFilter(communityMembers) : communityMembers,
112
+ data: isEventModel ? applyFilter(communityMembers, params) : communityMembers,
105
113
  hasNextPage: !!data.params?.page,
106
114
  loading: data.loading,
107
115
  error: data.error,
@@ -1,5 +1,5 @@
1
+ import { getPastDate } from '~/core/model';
1
2
  import { disableCache, enableCache } from '~/cache/api';
2
-
3
3
  import {
4
4
  client,
5
5
  connectClient,
@@ -19,7 +19,10 @@ import {
19
19
  convertedCommunityUser3,
20
20
  } from '~/utils/tests';
21
21
 
22
- import { getMembers } from '../getMembers';
22
+ // makes it easier to spy on applyFilter
23
+ import * as getMembersModule from '../getMembers';
24
+
25
+ const { getMembers, applyFilter } = getMembersModule;
23
26
 
24
27
  const getSnapshot = (params?: Record<string, any>) => {
25
28
  return {
@@ -166,4 +169,79 @@ describe('getMembers', () => {
166
169
  ),
167
170
  );
168
171
  });
172
+
173
+ test('it should apply fileters on RTE only', async () => {
174
+ const callback = jest.fn();
175
+ const applyFilterSpy = jest.spyOn(getMembersModule, 'applyFilter');
176
+ client.http.get = jest.fn().mockResolvedValue(communityUserQueryResponse);
177
+
178
+ getMembers({ communityId, sortBy: 'firstCreated' }, callback);
179
+ await pause();
180
+
181
+ expect(applyFilterSpy).not.toHaveBeenCalled();
182
+
183
+ client.emitter.emit('community.joined', {
184
+ communities: [community11],
185
+ communityUsers: [communityUser13],
186
+ users: [user13],
187
+ files: [],
188
+ categories: [],
189
+ feeds: [],
190
+ });
191
+ await pause();
192
+
193
+ expect(applyFilterSpy).toHaveBeenCalled();
194
+ });
195
+ });
196
+
197
+ describe('getMembers > applyFilter', () => {
198
+ const { communityId } = community11;
199
+
200
+ const m1 = {
201
+ communityId,
202
+ userId: 'test',
203
+ communityMembership: 'member',
204
+ roles: ['test-role'],
205
+ createdAt: new Date().toISOString(),
206
+ } as Amity.Membership<'community'>;
207
+
208
+ const m2 = {
209
+ communityId,
210
+ userId: 'searchable',
211
+ communityMembership: 'banned',
212
+ createdAt: getPastDate(),
213
+ } as Amity.Membership<'community'>;
214
+
215
+ const filters: [
216
+ string,
217
+ Amity.CommunityMemberLiveCollection,
218
+ Amity.Membership<'community'>[],
219
+ Amity.Membership<'community'>[],
220
+ ][] = [
221
+ ['it should filter by roles', { communityId, roles: ['test-role'] }, [m1, m2], [m1]],
222
+ [
223
+ 'it should filter by membership:member',
224
+ { communityId, membership: ['member'] },
225
+ [m1, m2],
226
+ [m1],
227
+ ],
228
+ [
229
+ 'it should filter by membership:banned',
230
+ { communityId, membership: ['banned'] },
231
+ [m1, m2],
232
+ [m2],
233
+ ],
234
+ ['it should sort by last created', { communityId }, [m1, m2], [m1, m2]],
235
+ [
236
+ 'it should sort by first created',
237
+ { communityId, sortBy: 'firstCreated' },
238
+ [m1, m2],
239
+ [m2, m1],
240
+ ],
241
+ ['it should filter by search term', { communityId, search: 'sea' }, [m1, m2], [m2]],
242
+ ];
243
+
244
+ test.each(filters)('%s', (test, param, input, expected) => {
245
+ expect(applyFilter(input, param)).toStrictEqual(expected);
246
+ });
169
247
  });
@@ -31,10 +31,10 @@ import { CACHE_SHORTEN_LIFESPAN } from '~/cache/utils';
31
31
  */
32
32
  /**
33
33
  * ```js
34
- * import { getCommunities } from '@amityco/ts-sdk'
34
+ * import { CommunityRepository } from '@amityco/ts-sdk'
35
35
  *
36
36
  * let communities = []
37
- * const unsub = getCommunities({
37
+ * const unsub = CommunityRepository.getCommunities({
38
38
  * displayName: Amity.Community['displayName'],
39
39
  * }, response => merge(communities, response.data))
40
40
  * ```
@@ -14,11 +14,11 @@ import {
14
14
  */
15
15
  /**
16
16
  * ```js
17
- * import { getCommunity } from '@amityco/ts-sdk';
17
+ * import { CommunityRepository } from '@amityco/ts-sdk';
18
18
  *
19
19
  * let community;
20
20
  *
21
- * const unsubscribe = getCommunity(communityId, response => {
21
+ * const unsub = CommunityRepository.getCommunity(communityId, response => {
22
22
  * community = response.data;
23
23
  * });
24
24
  * ```