@amityco/ts-sdk 0.0.1-beta.37 → 0.0.1-beta.38

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 (179) hide show
  1. package/.eslintrc.json +3 -5
  2. package/dist/@types/core/events.d.ts +1 -0
  3. package/dist/@types/core/events.d.ts.map +1 -1
  4. package/dist/@types/domains/category.d.ts +7 -0
  5. package/dist/@types/domains/category.d.ts.map +1 -1
  6. package/dist/@types/domains/community.d.ts +12 -0
  7. package/dist/@types/domains/community.d.ts.map +1 -1
  8. package/dist/@types/global.d.ts +5 -0
  9. package/dist/@types/global.d.ts.map +1 -1
  10. package/dist/category/api/queryCategories.d.ts +1 -5
  11. package/dist/category/api/queryCategories.d.ts.map +1 -1
  12. package/dist/category/observers/index.d.ts +2 -0
  13. package/dist/category/observers/index.d.ts.map +1 -0
  14. package/dist/category/observers/liveCategories.d.ts +18 -0
  15. package/dist/category/observers/liveCategories.d.ts.map +1 -0
  16. package/dist/category/observers/tests/liveCategories.test.d.ts +2 -0
  17. package/dist/category/observers/tests/liveCategories.test.d.ts.map +1 -0
  18. package/dist/channel/api/tests/getChannels.test.d.ts +2 -0
  19. package/dist/channel/api/tests/getChannels.test.d.ts.map +1 -0
  20. package/dist/channel/api/tests/leaveChannel.test.d.ts +2 -0
  21. package/dist/channel/api/tests/leaveChannel.test.d.ts.map +1 -0
  22. package/dist/channel/observers/liveChannel.d.ts.map +1 -1
  23. package/dist/client/api/accessTokenExpiryWatcher.d.ts +4 -1
  24. package/dist/client/api/accessTokenExpiryWatcher.d.ts.map +1 -1
  25. package/dist/client/api/getToken.d.ts +3 -1
  26. package/dist/client/api/getToken.d.ts.map +1 -1
  27. package/dist/client/utils/setClientToken.d.ts +3 -3
  28. package/dist/comment/api/deleteComment.d.ts.map +1 -1
  29. package/dist/comment/api/getComment.d.ts.map +1 -1
  30. package/dist/comment/observers/index.d.ts +1 -0
  31. package/dist/comment/observers/index.d.ts.map +1 -1
  32. package/dist/comment/observers/liveComment.d.ts +21 -0
  33. package/dist/comment/observers/liveComment.d.ts.map +1 -0
  34. package/dist/comment/observers/tests/liveComment.test.d.ts +2 -0
  35. package/dist/comment/observers/tests/liveComment.test.d.ts.map +1 -0
  36. package/dist/community/api/queryCommunities.d.ts +1 -10
  37. package/dist/community/api/queryCommunities.d.ts.map +1 -1
  38. package/dist/community/events/index.d.ts +1 -0
  39. package/dist/community/events/index.d.ts.map +1 -1
  40. package/dist/community/events/onCommunityUserChanged.d.ts +17 -0
  41. package/dist/community/events/onCommunityUserChanged.d.ts.map +1 -0
  42. package/dist/community/events/utils.d.ts +1 -0
  43. package/dist/community/events/utils.d.ts.map +1 -1
  44. package/dist/community/observers/index.d.ts +1 -0
  45. package/dist/community/observers/index.d.ts.map +1 -1
  46. package/dist/community/observers/liveCommunities.d.ts +20 -0
  47. package/dist/community/observers/liveCommunities.d.ts.map +1 -0
  48. package/dist/community/observers/tests/liveCommunities.test.d.ts +2 -0
  49. package/dist/community/observers/tests/liveCommunities.test.d.ts.map +1 -0
  50. package/dist/core/events.d.ts +3 -3
  51. package/dist/core/events.d.ts.map +1 -1
  52. package/dist/core/query/sorting.d.ts +6 -0
  53. package/dist/core/query/sorting.d.ts.map +1 -1
  54. package/dist/core/transports/http.d.ts +0 -5
  55. package/dist/core/transports/http.d.ts.map +1 -1
  56. package/dist/file/api/test/createImage.test.d.ts +2 -0
  57. package/dist/file/api/test/createImage.test.d.ts.map +1 -0
  58. package/dist/file/api/test/createVideo.test.d.ts +2 -0
  59. package/dist/file/api/test/createVideo.test.d.ts.map +1 -0
  60. package/dist/index.cjs.js +441 -195
  61. package/dist/index.d.ts +1 -0
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.esm.js +436 -195
  64. package/dist/index.umd.js +4 -4
  65. package/dist/message/observers/liveMessage.d.ts.map +1 -1
  66. package/dist/post/observers/index.d.ts +1 -0
  67. package/dist/post/observers/index.d.ts.map +1 -1
  68. package/dist/post/observers/livePost.d.ts +21 -0
  69. package/dist/post/observers/livePost.d.ts.map +1 -0
  70. package/dist/post/observers/tests/livePost.test.d.ts +2 -0
  71. package/dist/post/observers/tests/livePost.test.d.ts.map +1 -0
  72. package/dist/subChannel/api/tests/deleteSubChannel.test.d.ts +2 -0
  73. package/dist/subChannel/api/tests/deleteSubChannel.test.d.ts.map +1 -0
  74. package/dist/subChannel/api/tests/getSubChannel.test.d.ts +2 -0
  75. package/dist/subChannel/api/tests/getSubChannel.test.d.ts.map +1 -0
  76. package/dist/subChannel/api/tests/getSubChannels.test.d.ts +2 -0
  77. package/dist/subChannel/api/tests/getSubChannels.test.d.ts.map +1 -0
  78. package/dist/subChannel/api/tests/updateSubChannel.test.d.ts +2 -0
  79. package/dist/subChannel/api/tests/updateSubChannel.test.d.ts.map +1 -0
  80. package/dist/subChannel/observers/liveSubChannel.d.ts.map +1 -1
  81. package/dist/user/api/tests/updateUser.test.d.ts +2 -0
  82. package/dist/user/api/tests/updateUser.test.d.ts.map +1 -0
  83. package/dist/user/observers/liveUser.d.ts.map +1 -1
  84. package/dist/utils/liveObject.d.ts +2 -0
  85. package/dist/utils/liveObject.d.ts.map +1 -0
  86. package/dist/utils/tests/dummy/category.d.ts +64 -0
  87. package/dist/utils/tests/dummy/category.d.ts.map +1 -0
  88. package/dist/utils/tests/dummy/channel.d.ts +50 -0
  89. package/dist/utils/tests/dummy/channel.d.ts.map +1 -1
  90. package/dist/utils/tests/dummy/community.d.ts +132 -0
  91. package/dist/utils/tests/dummy/community.d.ts.map +1 -1
  92. package/dist/utils/tests/dummy/file.d.ts +3 -0
  93. package/dist/utils/tests/dummy/file.d.ts.map +1 -1
  94. package/dist/utils/tests/dummy/index.d.ts +1 -0
  95. package/dist/utils/tests/dummy/index.d.ts.map +1 -1
  96. package/dist/utils/tests/dummy/post.d.ts +2 -0
  97. package/dist/utils/tests/dummy/post.d.ts.map +1 -1
  98. package/dist/utils/tests/dummy/subChannel.d.ts +0 -20
  99. package/dist/utils/tests/dummy/subChannel.d.ts.map +1 -1
  100. package/dist/utils/tests/dummy/user.d.ts +18 -0
  101. package/dist/utils/tests/dummy/user.d.ts.map +1 -1
  102. package/dist/utils/tests/liveObject.test.d.ts +2 -0
  103. package/dist/utils/tests/liveObject.test.d.ts.map +1 -0
  104. package/package.json +4 -4
  105. package/src/@types/core/events.ts +1 -0
  106. package/src/@types/domains/category.ts +13 -0
  107. package/src/@types/domains/community.ts +25 -0
  108. package/src/@types/global.ts +5 -0
  109. package/src/category/api/queryCategories.ts +3 -5
  110. package/src/category/observers/index.ts +1 -0
  111. package/src/category/observers/liveCategories.ts +141 -0
  112. package/src/category/observers/tests/liveCategories.test.ts +147 -0
  113. package/src/channel/api/tests/createChannel.test.ts +30 -6
  114. package/src/channel/api/tests/getChannel.test.ts +3 -1
  115. package/src/channel/api/tests/getChannels.test.ts +97 -0
  116. package/src/channel/api/tests/joinChannel.test.ts +62 -3
  117. package/src/channel/api/tests/leaveChannel.test.ts +90 -0
  118. package/src/channel/api/tests/queryChannels.test.ts +38 -1
  119. package/src/channel/observers/liveChannel.ts +8 -80
  120. package/src/client/api/accessTokenExpiryWatcher.ts +7 -5
  121. package/src/client/api/tests/accessTokenExpiryWatcher.test.ts +8 -5
  122. package/src/comment/api/deleteComment.ts +5 -5
  123. package/src/comment/api/getComment.ts +8 -3
  124. package/src/comment/observers/index.ts +1 -0
  125. package/src/comment/observers/liveComment.ts +43 -0
  126. package/src/comment/observers/tests/liveComment.test.ts +95 -0
  127. package/src/community/api/queryCommunities.ts +3 -10
  128. package/src/community/api/test/addCommunityMember.test.ts +14 -2
  129. package/src/community/api/test/joinCommunity.test.ts +14 -2
  130. package/src/community/api/test/leaveCommunity.test.ts +11 -1
  131. package/src/community/api/test/removeCommunityMembers.test.ts +11 -1
  132. package/src/community/events/index.ts +1 -0
  133. package/src/community/events/onCommunityUserChanged.ts +20 -0
  134. package/src/community/events/test/onCommunityJoined.test.ts +1 -1
  135. package/src/community/events/test/onCommunityUserAdded.test.ts +1 -1
  136. package/src/community/events/test/onCommunityUserBanned.test.ts +1 -1
  137. package/src/community/events/test/onCommunityUserUnbaned.test.ts +1 -1
  138. package/src/community/events/test/utils.test.ts +52 -3
  139. package/src/community/events/utils.ts +49 -0
  140. package/src/community/observers/index.ts +1 -0
  141. package/src/community/observers/liveCommunities.ts +188 -0
  142. package/src/community/observers/tests/liveCommunities.test.ts +284 -0
  143. package/src/core/query/sorting.ts +8 -0
  144. package/src/core/transports/http.ts +17 -13
  145. package/src/core/transports/test/http.test.ts +49 -60
  146. package/src/file/api/createFile.ts +1 -1
  147. package/src/file/api/createImage.ts +1 -1
  148. package/src/file/api/createVideo.ts +1 -1
  149. package/src/file/api/test/createImage.test.ts +69 -0
  150. package/src/file/api/test/createVideo.test.ts +81 -0
  151. package/src/index.ts +1 -0
  152. package/src/message/observers/liveMessage.ts +11 -83
  153. package/src/message/tests/observers/liveMessage.test.ts +1 -143
  154. package/src/post/observers/index.ts +1 -0
  155. package/src/post/observers/livePost.ts +47 -0
  156. package/src/post/observers/tests/livePost.test.ts +97 -0
  157. package/src/stream/api/tests/createStream.test.ts +3 -11
  158. package/src/stream/api/tests/deleteStream.test.ts +5 -3
  159. package/src/subChannel/api/tests/createSubChannel.test.ts +21 -14
  160. package/src/subChannel/api/tests/deleteSubChannel.test.ts +112 -0
  161. package/src/subChannel/api/tests/getSubChannel.test.ts +97 -0
  162. package/src/subChannel/api/tests/getSubChannels.test.ts +97 -0
  163. package/src/subChannel/api/tests/updateSubChannel.test.ts +86 -0
  164. package/src/subChannel/observers/liveSubChannel.ts +6 -56
  165. package/src/subChannel/observers/tests/liveSubChannel.test.ts +0 -82
  166. package/src/user/api/tests/updateUser.test.ts +60 -0
  167. package/src/user/observers/liveUser.ts +9 -61
  168. package/src/user/tests/observers/liveUser.test.ts +1 -154
  169. package/src/utils/liveObject.ts +86 -0
  170. package/src/utils/tests/dummy/category.ts +57 -0
  171. package/src/utils/tests/dummy/channel.ts +51 -1
  172. package/src/utils/tests/dummy/community.ts +94 -0
  173. package/src/utils/tests/dummy/file.ts +32 -0
  174. package/src/utils/tests/dummy/index.ts +1 -0
  175. package/src/utils/tests/dummy/post.ts +56 -45
  176. package/src/utils/tests/dummy/stream.ts +73 -73
  177. package/src/utils/tests/dummy/subChannel.ts +0 -22
  178. package/src/utils/tests/dummy/user.ts +21 -0
  179. package/src/utils/tests/liveObject.test.ts +172 -0
@@ -4,11 +4,17 @@ import { disableCache, enableCache, pushToCache } from '~/cache/api';
4
4
  import { ingestInCache } from '~/cache/api/ingestInCache';
5
5
 
6
6
  import { prepareChannelPayload } from '~/channel/utils';
7
- import { client, channelQueryResponse } from '~/utils/tests';
7
+ import {
8
+ client,
9
+ channelQueryResponse,
10
+ channelTagQueryResponse,
11
+ channelExcludeTagQueryResponse,
12
+ } from '~/utils/tests';
8
13
 
9
14
  import { queryChannels } from '../queryChannels';
10
15
 
11
16
  describe('queryChannels', () => {
17
+ // integration_test_id: 06c14dab-4799-4f26-9e52-be7c12b3bdb3
12
18
  test('it should return channels', async () => {
13
19
  const expected = prepareChannelPayload(channelQueryResponse.data).channels;
14
20
  client.http.get = jest.fn().mockResolvedValue(channelQueryResponse);
@@ -18,6 +24,37 @@ describe('queryChannels', () => {
18
24
  expect(data).toEqual(expected);
19
25
  });
20
26
 
27
+ // integration_test_id: 253fb0ac-f868-4570-9b1e-98b08861aa53
28
+ test('it should return channels match with membership type', async () => {
29
+ // Actually there is no any flag to tell about this list is relate to membership type
30
+ // But need to implement this case to match with our test list
31
+ const expected = prepareChannelPayload(channelQueryResponse.data).channels;
32
+ client.http.get = jest.fn().mockResolvedValue(channelQueryResponse);
33
+ const { data } = await queryChannels({ membership: 'member' });
34
+ expect(data).toEqual(expected);
35
+ });
36
+
37
+ // integration_test_id: 92329d41-9403-44e7-979f-ed227e6ab120
38
+ test('it should return channels match with tags query type', async () => {
39
+ const expected = prepareChannelPayload(channelTagQueryResponse.data).channels;
40
+ client.http.get = jest.fn().mockResolvedValue(channelTagQueryResponse);
41
+ const { data } = await queryChannels({ tags: ['tag1'] });
42
+ expect(data).toEqual(expected);
43
+ expect(data[0].tags).toContain('tag1');
44
+ });
45
+
46
+ // integration_test_id: 5249778c-6d99-4e2f-9b80-2f4ea6ae1833
47
+ test('it should return channels without tags which defined in exclude options', async () => {
48
+ const expected = prepareChannelPayload(channelExcludeTagQueryResponse.data).channels;
49
+ client.http.get = jest.fn().mockResolvedValue(channelExcludeTagQueryResponse);
50
+ const { data } = await queryChannels({ excludeTags: ['tag1'] });
51
+ expect(data).toEqual(expected);
52
+
53
+ data.forEach(item => {
54
+ expect(item.tags).not.toContain('tag1');
55
+ });
56
+ });
57
+
21
58
  test('it should throw error', async () => {
22
59
  client.http.get = jest.fn().mockRejectedValueOnce(new Error('error'));
23
60
 
@@ -1,12 +1,4 @@
1
- import { ASCApiError } from '~/core/errors';
2
- import { getActiveClient } from '~/client/api';
3
- import { createQuery, runQuery } from '~/core/query';
4
- import {
5
- LIVE_OBJECT_ENABLE_CACHE_MESSAGE,
6
- UNSYNCED_OBJECT_CACHED_AT_MESSAGE,
7
- UNSYNCED_OBJECT_CACHED_AT_VALUE,
8
- } from '~/utils/constants';
9
- import { hasUpdates } from '~/core/model';
1
+ import { liveObject } from '~/utils/liveObject';
10
2
  import { onMessageCreated } from '~/message/events';
11
3
  import { getChannel } from '../api';
12
4
  import { onChannelDeleted, onChannelJoined, onChannelMuted, onChannelUpdated } from '../events';
@@ -34,75 +26,11 @@ export const liveChannel = (
34
26
  channelId: Amity.Channel['channelId'],
35
27
  callback: Amity.LiveObjectCallback<Amity.Channel>,
36
28
  ): Amity.Unsubscriber => {
37
- const { log, cache } = getActiveClient();
38
- const timestamp = Date.now();
39
- log(`liveChannel(tmpid: ${timestamp}) > listen`);
40
-
41
- if (!cache) {
42
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
43
- }
44
-
45
- let channel: Amity.Channel;
46
- let isUnsyncedObject = false;
47
- const disposers: Amity.Unsubscriber[] = [];
48
-
49
- const dispatcher = (data: Amity.LiveObject<Amity.Channel>) => {
50
- channel = data.data;
51
- callback(data);
52
- };
53
-
54
- const realtimeRouter = (eventChannel: Amity.Channel) => {
55
- if (channelId !== eventChannel.channelId) {
56
- return;
57
- }
58
-
59
- if (channel && !hasUpdates(channel, eventChannel)) {
60
- return;
61
- }
62
-
63
- dispatcher({ loading: false, data: eventChannel, origin: 'event' });
64
- };
65
-
66
- const onFetch = () => {
67
- const query = createQuery(getChannel, channelId);
68
-
69
- runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
70
- if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
71
- dispatcher({
72
- data,
73
- origin,
74
- loading: false,
75
- error: new ASCApiError(
76
- UNSYNCED_OBJECT_CACHED_AT_MESSAGE,
77
- Amity.ClientError.DISALOOW_UNSYNCED_OBJECT,
78
- Amity.ErrorLevel.ERROR,
79
- ),
80
- });
81
-
82
- isUnsyncedObject = true;
83
- disposers.forEach(fn => fn());
84
- } else if (!isUnsyncedObject) {
85
- dispatcher({ loading, data, origin, error });
86
- }
87
-
88
- if (error) {
89
- disposers.forEach(fn => fn());
90
- }
91
- });
92
- };
93
-
94
- disposers.push(
95
- onChannelUpdated(realtimeRouter),
96
- onChannelDeleted(realtimeRouter),
97
- onChannelJoined(realtimeRouter),
98
- onChannelMuted(realtimeRouter),
99
- onMessageCreated(() => null), // watch unread count
100
- );
101
-
102
- onFetch();
103
-
104
- return () => {
105
- log(`liveChannel(tmpid: ${timestamp}) > dispose`);
106
- disposers.forEach(fn => fn());
107
- };
29
+ return liveObject(channelId, callback, 'channelId', getChannel, [
30
+ onChannelUpdated,
31
+ onChannelDeleted,
32
+ onChannelJoined,
33
+ onChannelMuted,
34
+ () => onMessageCreated(() => null), // watch unread count
35
+ ]);
108
36
  };
@@ -26,10 +26,12 @@ export const isExpired = (expiresAt: Amity.Tokens['expiresAt']): boolean =>
26
26
  *
27
27
  * @category private
28
28
  */
29
- export const isAboutToExpire = (
30
- expiresAt: Amity.Tokens['expiresAt'],
31
- issuedAt: Amity.Tokens['issuedAt'],
32
- ): boolean => {
29
+ export const isAboutToExpire = (params: {
30
+ expiresAt: Amity.Tokens['expiresAt'];
31
+ issuedAt: Amity.Tokens['issuedAt'];
32
+ }): boolean => {
33
+ const { expiresAt, issuedAt } = params;
34
+
33
35
  const expires = Date.parse(expiresAt);
34
36
  const issued = Date.parse(issuedAt);
35
37
  const now = Date.now();
@@ -74,7 +76,7 @@ export const accessTokenExpiryWatcher = (
74
76
  return;
75
77
  }
76
78
 
77
- if (isAboutToExpire(issuedAt, expiresAt)) {
79
+ if (isAboutToExpire({ expiresAt, issuedAt })) {
78
80
  sessionHandler.sessionWillRenewAccessToken(renewal());
79
81
  }
80
82
  }, ACCESS_TOKEN_WATCHER_INTERVAL);
@@ -96,19 +96,22 @@ describe('accessTokenExpiryWatcher > aboutToExpire', () => {
96
96
 
97
97
  aboutToExpireTime.setHours(aboutToExpireTime.getHours() + 1);
98
98
 
99
- expect(isAboutToExpire(aboutToExpireTime.toISOString(), oldIssuedAtTime.toISOString())).toBe(
100
- true,
101
- );
99
+ expect(
100
+ isAboutToExpire({
101
+ expiresAt: aboutToExpireTime.toISOString(),
102
+ issuedAt: oldIssuedAtTime.toISOString(),
103
+ }),
104
+ ).toBe(true);
102
105
  });
103
106
 
104
107
  test('it should return false if token expired', () => {
105
- expect(isAboutToExpire(expiresAt, issuedAt)).toBe(false);
108
+ expect(isAboutToExpire({ expiresAt, issuedAt })).toBe(false);
106
109
  });
107
110
 
108
111
  test('it should return false if not about to expire', () => {
109
112
  oldIssuedAtTime.setDate(oldIssuedAtTime.getDate() - 10);
110
113
 
111
- expect(isAboutToExpire(expiresAt, issuedAt)).toBe(false);
114
+ expect(isAboutToExpire({ expiresAt, issuedAt })).toBe(false);
112
115
  });
113
116
  });
114
117
 
@@ -1,10 +1,12 @@
1
1
  import { getActiveClient } from '~/client/api';
2
2
 
3
- import { dropFromCache, upsertInCache } from '~/cache/api';
3
+ import { upsertInCache } from '~/cache/api';
4
4
  import { fireEvent } from '~/core/events';
5
5
 
6
- import { getComment } from './getComment';
7
6
  import { getPost } from '~/post/api/getPost';
7
+ import { pushToTombstone } from '~/cache/api/pushToTombstone';
8
+ import { scheduleTask } from '~/core/microtasks';
9
+ import { getComment } from './getComment';
8
10
 
9
11
  /**
10
12
  * ```js
@@ -49,9 +51,7 @@ export const deleteComment = async (
49
51
  fireEvent('comment.deleted', { comments: [deleted] });
50
52
 
51
53
  if (permanent) {
52
- setTimeout(() => {
53
- dropFromCache(['comment', 'get', commentId], true);
54
- }, 0);
54
+ scheduleTask(() => pushToTombstone('comment', commentId));
55
55
  } else {
56
56
  upsertInCache(['comment', 'get', commentId], { isDeleted: true });
57
57
  }
@@ -1,7 +1,10 @@
1
1
  import { getActiveClient } from '~/client/api';
2
2
 
3
- import { pullFromCache, dropFromCache } from '~/cache/api';
3
+ import { pullFromCache } from '~/cache/api';
4
4
  import { ingestInCache } from '~/cache/api/ingestInCache';
5
+ import { isInTombstone } from '~/cache/api/isInTombstone';
6
+ import { checkIfShouldGoesToTombstone } from '~/cache/utils';
7
+ import { pushToTombstone } from '~/cache/api/pushToTombstone';
5
8
 
6
9
  /**
7
10
  * ```js
@@ -23,6 +26,8 @@ export const getComment = async (
23
26
  const client = getActiveClient();
24
27
  client.log('comment/getComment', commentId);
25
28
 
29
+ isInTombstone('comment', commentId);
30
+
26
31
  let data: Amity.CommentPayload;
27
32
 
28
33
  try {
@@ -33,8 +38,8 @@ export const getComment = async (
33
38
 
34
39
  data = response.data;
35
40
  } catch (error) {
36
- if ((error as Amity.ErrorResponse)?.code === Amity.ServerError.ITEM_NOT_FOUND) {
37
- dropFromCache(['comment', 'get', commentId], true);
41
+ if (checkIfShouldGoesToTombstone((error as Amity.ErrorResponse)?.code)) {
42
+ pushToTombstone('comment', commentId);
38
43
  }
39
44
 
40
45
  throw error;
@@ -1,3 +1,4 @@
1
1
  export * from './observeComments';
2
2
  export * from './observeComment';
3
+ export * from './liveComment';
3
4
  export * from './liveComments';
@@ -0,0 +1,43 @@
1
+ import { liveObject } from '~/utils/liveObject';
2
+ import { getComment } from '../api';
3
+ import {
4
+ onCommentDeleted,
5
+ onCommentFlagged,
6
+ onCommentReactionAdded,
7
+ onCommentReactionRemoved,
8
+ onCommentUnflagged,
9
+ onCommentUpdated,
10
+ } from '../events';
11
+
12
+ /**
13
+ * ```js
14
+ * import { liveComment } from '@amityco/ts-sdk';
15
+ *
16
+ * let comment;
17
+ *
18
+ * const unsubscribe = liveComment(commentId, response => {
19
+ * comment = response.data;
20
+ * });
21
+ * ```
22
+ *
23
+ * Observe all mutation on a given {@link Amity.Comment}
24
+ *
25
+ * @param commentId the ID of the comment to observe
26
+ * @param callback the function to call when new data are available
27
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the comment
28
+ *
29
+ * @category Comment Live Object
30
+ */
31
+ export const liveComment = (
32
+ commentId: Amity.Comment['commentId'],
33
+ callback: Amity.LiveObjectCallback<Amity.Comment>,
34
+ ): Amity.Unsubscriber => {
35
+ return liveObject(commentId, callback, 'commentId', getComment, [
36
+ onCommentDeleted,
37
+ onCommentFlagged,
38
+ onCommentReactionAdded,
39
+ onCommentReactionRemoved,
40
+ onCommentUnflagged,
41
+ onCommentUpdated,
42
+ ]);
43
+ };
@@ -0,0 +1,95 @@
1
+ import { disableCache, enableCache } from '~/cache/api';
2
+ import {
3
+ pause,
4
+ client,
5
+ connectClient,
6
+ disconnectClient,
7
+ generateComment,
8
+ user12,
9
+ } from '~/utils/tests';
10
+ import { getFutureDate } from '~/core/model';
11
+ import { liveComment } from '../liveComment';
12
+
13
+ describe('liveComment', () => {
14
+ const comment = generateComment();
15
+ const response = { data: { comments: [comment] } };
16
+
17
+ beforeAll(async () => {
18
+ await connectClient();
19
+ });
20
+
21
+ afterAll(async () => {
22
+ await disconnectClient();
23
+ });
24
+
25
+ beforeEach(enableCache);
26
+
27
+ afterEach(disableCache);
28
+
29
+ const events: [string, keyof Amity.MqttCommentEvents][] = [
30
+ ['should get update on comment.updated event', 'comment.updated'],
31
+ ['should get update on comment.deleted event', 'comment.deleted'],
32
+ ['should get update on comment.flagged event', 'comment.flagged'],
33
+ ['should get update on comment.unflagged event', 'comment.unflagged'],
34
+ ];
35
+
36
+ test.each(events)('%s', async (test, event) => {
37
+ const update = {
38
+ ...comment,
39
+ data: { text: 'new-text' },
40
+ updatedAt: getFutureDate(comment.updatedAt),
41
+ };
42
+
43
+ const callback = jest.fn();
44
+ client.http.get = jest.fn().mockResolvedValue(response);
45
+
46
+ liveComment(comment.commentId, callback);
47
+ await pause();
48
+ client.emitter.emit(event, { comments: [update] });
49
+ await pause();
50
+
51
+ expect(callback).toHaveBeenCalledTimes(3);
52
+ expect(callback).toHaveBeenNthCalledWith(
53
+ 3,
54
+ expect.objectContaining({
55
+ data: update,
56
+ loading: false,
57
+ }),
58
+ );
59
+ });
60
+
61
+ test.each([
62
+ ['should get update on comment.addReaction event', 'comment.addReaction'],
63
+ ['should get update on comment.removeReaction event', 'comment.removeReaction'],
64
+ ] as [string, keyof Amity.MqttCommentEvents][])('%s', async (test, event) => {
65
+ const update = {
66
+ ...comment,
67
+ data: { text: 'new-text' },
68
+ updatedAt: getFutureDate(comment.updatedAt),
69
+ };
70
+ const reactor: Amity.Reaction = {
71
+ createdAt: getFutureDate(comment.updatedAt),
72
+ reactionId: 'like',
73
+ reactionName: 'like',
74
+ referenceId: comment.commentId,
75
+ referenceType: 'comment',
76
+ userId: user12.userId,
77
+ };
78
+ const callback = jest.fn();
79
+ client.http.get = jest.fn().mockResolvedValue(response);
80
+
81
+ liveComment(comment.commentId, callback);
82
+ await pause();
83
+ client.emitter.emit(event, { comments: [update], reactor });
84
+ await pause();
85
+
86
+ expect(callback).toHaveBeenCalledTimes(3);
87
+ expect(callback).toHaveBeenNthCalledWith(
88
+ 3,
89
+ expect.objectContaining({
90
+ data: update,
91
+ loading: false,
92
+ }),
93
+ );
94
+ });
95
+ });
@@ -22,16 +22,9 @@ import { unpackCommunityPayload } from '../utils';
22
22
  * @category Community API
23
23
  * @async
24
24
  */
25
- export const queryCommunities = async (query?: {
26
- displayName?: string;
27
- membership?: 'all' | 'member' | 'notMember';
28
- categoryId?: Amity.Category['categoryId'];
29
- isDeleted?: Amity.Community['isDeleted'];
30
- hasFlag?: boolean;
31
- tags?: Amity.Taggable['tags'];
32
- sortBy?: 'displayName' | 'firstCreated' | 'lastCreated';
33
- page?: Amity.Page;
34
- }): Promise<Amity.Cached<Amity.Paged<Amity.Community>>> => {
25
+ export const queryCommunities = async (
26
+ query?: Amity.QueryCommunities,
27
+ ): Promise<Amity.Cached<Amity.Paged<Amity.Community>>> => {
35
28
  const client = getActiveClient();
36
29
  client.log('channel/queryCommunities', query);
37
30
 
@@ -1,7 +1,14 @@
1
1
  import { disableCache, enableCache, pullFromCache } from '~/cache/api';
2
2
  import { getResolver } from '~/core/model';
3
3
 
4
- import { client, community11, communityUser11, user11 } from '~/utils/tests';
4
+ import {
5
+ client,
6
+ connectClient,
7
+ disconnectClient,
8
+ community11,
9
+ communityUser11,
10
+ user11,
11
+ } from '~/utils/tests';
5
12
 
6
13
  import { onCommunityUserAdded } from '../../events';
7
14
  import { addCommunityMembers } from '../addCommunityMembers';
@@ -21,6 +28,9 @@ const resolvedPostValue = {
21
28
  };
22
29
 
23
30
  describe('addCommunityMembers', () => {
31
+ beforeAll(connectClient);
32
+ afterAll(disconnectClient);
33
+
24
34
  test('should return true value', async () => {
25
35
  client.http.post = jest.fn().mockResolvedValue(resolvedPostValue);
26
36
 
@@ -66,6 +76,8 @@ describe('addCommunityMembers', () => {
66
76
 
67
77
  await addCommunityMembers(communityToAddUserTo.communityId, [userToAdd.userId]);
68
78
 
69
- await expect(callback).resolves.toEqual(expect.objectContaining(communityToAddUserTo));
79
+ await expect(callback).resolves.toEqual(
80
+ expect.objectContaining({ ...communityToAddUserTo, isJoined: true }),
81
+ );
70
82
  });
71
83
  });
@@ -1,7 +1,14 @@
1
1
  import { disableCache, enableCache, pullFromCache } from '~/cache/api';
2
2
  import { getResolver } from '~/core/model';
3
3
 
4
- import { client, community11, communityUser11, user11 } from '~/utils/tests';
4
+ import {
5
+ client,
6
+ connectClient,
7
+ disconnectClient,
8
+ community11,
9
+ communityUser11,
10
+ user11,
11
+ } from '~/utils/tests';
5
12
 
6
13
  import { onCommunityJoined } from '../../events';
7
14
  import { joinCommunity } from '../joinCommunity';
@@ -21,6 +28,9 @@ const resolvedPostValue = {
21
28
  };
22
29
 
23
30
  describe('joinCommunity', () => {
31
+ beforeAll(connectClient);
32
+ afterAll(disconnectClient);
33
+
24
34
  test('should return true value', async () => {
25
35
  client.http.post = jest.fn().mockResolvedValue(resolvedPostValue);
26
36
 
@@ -65,6 +75,8 @@ describe('joinCommunity', () => {
65
75
 
66
76
  await joinCommunity(communityToJoin.communityId);
67
77
 
68
- await expect(callback).resolves.toEqual(expect.objectContaining(communityToJoin));
78
+ await expect(callback).resolves.toEqual(
79
+ expect.objectContaining({ ...communityToJoin, isJoined: true }),
80
+ );
69
81
  });
70
82
  });
@@ -1,6 +1,13 @@
1
1
  import { disableCache, enableCache, pullFromCache, pushToCache } from '~/cache/api';
2
2
  import { getResolver } from '~/core/model';
3
- import { client, community11, communityUser11, user11 } from '~/utils/tests';
3
+ import {
4
+ client,
5
+ connectClient,
6
+ disconnectClient,
7
+ community11,
8
+ communityUser11,
9
+ user11,
10
+ } from '~/utils/tests';
4
11
 
5
12
  import { leaveCommunity } from '../leaveCommunity';
6
13
  import { onCommunityLeft } from '../../events';
@@ -21,6 +28,9 @@ const resolvedDeleteValue = {
21
28
  };
22
29
 
23
30
  describe('leaveCommunity', () => {
31
+ beforeAll(connectClient);
32
+ afterAll(disconnectClient);
33
+
24
34
  test('should return true value', async () => {
25
35
  client.http.delete = jest.fn().mockResolvedValueOnce(resolvedDeleteValue);
26
36
 
@@ -1,7 +1,14 @@
1
1
  import { disableCache, enableCache, pullFromCache } from '~/cache/api';
2
2
  import { getResolver } from '~/core/model';
3
3
 
4
- import { client, community11, communityUser11, user11 } from '~/utils/tests';
4
+ import {
5
+ client,
6
+ community11,
7
+ communityUser11,
8
+ user11,
9
+ connectClient,
10
+ disconnectClient,
11
+ } from '~/utils/tests';
5
12
 
6
13
  import { onCommunityUserRemoved } from '../../events';
7
14
  import { removeCommunityMembers } from '../removeCommunityMembers';
@@ -22,6 +29,9 @@ const resolvedDeleteValue = {
22
29
  };
23
30
 
24
31
  describe('removeCommunityMembers', () => {
32
+ beforeAll(connectClient);
33
+ afterAll(disconnectClient);
34
+
25
35
  test('should return true value', async () => {
26
36
  client.http.delete = jest.fn().mockResolvedValue(resolvedDeleteValue);
27
37
 
@@ -7,5 +7,6 @@ export * from './onCommunityLeft';
7
7
 
8
8
  export * from './onCommunityUserAdded';
9
9
  export * from './onCommunityUserRemoved';
10
+ export * from './onCommunityUserChanged';
10
11
  export * from './onCommunityUserBanned';
11
12
  export * from './onCommunityUserUnbanned';
@@ -0,0 +1,20 @@
1
+ import { createCommunityMemberEventSubscriber } from './utils';
2
+
3
+ /**
4
+ * ```js
5
+ * import { onCommunityUserChanged } from '@amityco/ts-sdk'
6
+ * const dispose = onCommunityUserChanged((community, member) => {
7
+ * // ...
8
+ * })
9
+ * ```
10
+ *
11
+ * Fired when a user has been added or removed from a {@link Amity.Community}
12
+ *
13
+ * @param callback The function to call when the event was fired
14
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
15
+ *
16
+ * @category Community Events
17
+ */
18
+ export const onCommunityUserChanged = (
19
+ callback: (community: Amity.Community, member: Amity.Membership<'community'>) => void,
20
+ ) => createCommunityMemberEventSubscriber('community.userChanged', callback);
@@ -35,7 +35,7 @@ describe('onCommunityJoined', () => {
35
35
  unsub();
36
36
 
37
37
  expect(callback).toHaveBeenCalled();
38
- expect(callback).toHaveBeenCalledWith(communityToJoin, joinedUser);
38
+ expect(callback).toHaveBeenCalledWith({ ...communityToJoin, isJoined: true }, joinedUser);
39
39
  });
40
40
 
41
41
  test('it should got nothing if we did unsubscribe before got event', () => {
@@ -35,7 +35,7 @@ describe('onCommunityUserAdded', () => {
35
35
  unsub();
36
36
 
37
37
  expect(callback).toHaveBeenCalled();
38
- expect(callback).toHaveBeenCalledWith(communityToAddUserTo, userToAdd);
38
+ expect(callback).toHaveBeenCalledWith({ ...communityToAddUserTo, isJoined: true }, userToAdd);
39
39
  });
40
40
 
41
41
  test('it should got nothing if we did unsubscribe before got event', () => {
@@ -35,7 +35,7 @@ describe('onCommunityUserBanned', () => {
35
35
  unsub();
36
36
 
37
37
  expect(callback).toHaveBeenCalled();
38
- expect(callback).toHaveBeenCalledWith(community, banedUser);
38
+ expect(callback).toHaveBeenCalledWith({ ...community, isJoined: true }, banedUser);
39
39
  });
40
40
 
41
41
  test('it should got nothing if we did unsubscribe before got event', () => {
@@ -35,7 +35,7 @@ describe('onCommunityUserUnbanned', () => {
35
35
  unsub();
36
36
 
37
37
  expect(callback).toHaveBeenCalled();
38
- expect(callback).toHaveBeenCalledWith(community, unbannedUser);
38
+ expect(callback).toHaveBeenCalledWith({ ...community, isJoined: true }, unbannedUser);
39
39
  });
40
40
 
41
41
  test('it should got nothing if we did unsubscribe before got event', () => {