@amityco/ts-sdk 6.3.2-c5c984d.0 → 6.3.2-eee54e8.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.
@@ -1 +1 @@
1
- {"version":3,"file":"getUsers.d.ts","sourceRoot":"","sources":["../../../src/userRepository/observers/getUsers.ts"],"names":[],"mappings":"AAiCA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,QAAQ,WACX,MAAM,kBAAkB,YACtB,MAAM,sBAAsB,CAAC,MAAM,IAAI,CAAC,WACzC,MAAM,oBAAoB,eAgHpC,CAAC"}
1
+ {"version":3,"file":"getUsers.d.ts","sourceRoot":"","sources":["../../../src/userRepository/observers/getUsers.ts"],"names":[],"mappings":"AAiCA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,QAAQ,WACX,MAAM,kBAAkB,YACtB,MAAM,sBAAsB,CAAC,MAAM,IAAI,CAAC,WACzC,MAAM,oBAAoB,eAuHpC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amityco/ts-sdk",
3
- "version": "6.3.2-c5c984d.0",
3
+ "version": "6.3.2-eee54e8.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",
@@ -69,14 +69,8 @@ export const getMembers = (
69
69
  const disposers: Amity.Unsubscriber[] = [];
70
70
  const cacheKey = ['channelUsers', 'collection', { channelId: params.channelId }];
71
71
 
72
- const responder = (data: Amity.ChannelMembersLiveCollectionCache) => {
73
- let channelMembers: Amity.Membership<'channel'>[] =
74
- data.data
75
- .map(id => pullFromCache<Amity.Membership<'channel'>>(['channelUsers', 'get', id])!)
76
- .filter(Boolean)
77
- .map(({ data }) => data) ?? [];
78
-
79
- channelMembers = filterByPropIntersection(channelMembers, 'roles', params.roles);
72
+ const applyFilter = <T extends Amity.Membership<'channel'>>(data: T[]): T[] => {
73
+ let channelMembers = filterByPropIntersection(data, 'roles', params.roles);
80
74
 
81
75
  if (params.memberships) {
82
76
  /*
@@ -106,9 +100,22 @@ export const getMembers = (
106
100
  sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated,
107
101
  );
108
102
 
103
+ return channelMembers;
104
+ };
105
+
106
+ const responder = (data: Amity.ChannelMembersLiveCollectionCache, isEventModel = false) => {
107
+ const channelMembers: Amity.Membership<'channel'>[] =
108
+ data.data
109
+ .map(id => pullFromCache<Amity.Membership<'channel'>>(['channelUsers', 'get', id])!)
110
+ .filter(Boolean)
111
+ .map(({ data }) => data) ?? [];
112
+
109
113
  callback({
110
114
  onNextPage: onFetch,
111
- data: channelMembers,
115
+ /*
116
+ * Only apply filter to RTE Model
117
+ */
118
+ data: isEventModel ? applyFilter(channelMembers) : channelMembers,
112
119
  hasNextPage: !!data.params?.page,
113
120
  loading: data.loading,
114
121
  error: data.error,
@@ -137,7 +144,7 @@ export const getMembers = (
137
144
  }
138
145
 
139
146
  pushToCache(cacheKey, collection);
140
- responder(collection);
147
+ responder(collection, true);
141
148
  };
142
149
 
143
150
  const onFetch = (initial = false) => {
@@ -59,68 +59,6 @@ describe('getMembers', () => {
59
59
  );
60
60
  });
61
61
 
62
- const filters: [string, Amity.ChannelMembersLiveCollection, Amity.Membership<'channel'>[]][] = [
63
- [
64
- 'roles',
65
- { channelId, roles: channelUserQueryResponsePage3.data.channelUsers[0].roles },
66
- [channelUserWithRole],
67
- ],
68
- ['searched term', { channelId, search: 'use' }, [channelUserWithRole, bannedChannelUser]],
69
- ['member', { channelId, memberships: ['member'] }, [channelUserWithRole, mutedChannelUser]],
70
- ['muted members', { channelId, memberships: ['muted'] }, [mutedChannelUser]],
71
- ['banned members', { channelId, memberships: ['banned'] }, [bannedChannelUser]],
72
- [
73
- 'muted and banned members',
74
- { channelId, memberships: ['muted', 'banned'] },
75
- [mutedChannelUser, bannedChannelUser],
76
- ],
77
- ];
78
-
79
- test.each(filters)('it should filter channelUsers by %s', async (filter, params, expected) => {
80
- const callback = jest.fn();
81
- client.http.get = jest.fn().mockResolvedValue(channelUserQueryResponsePage3);
82
-
83
- getMembers(params, callback);
84
- await pause();
85
-
86
- expect(callback).toHaveBeenNthCalledWith(1, expect.objectContaining(getSnapshot()));
87
- expect(callback).toHaveBeenNthCalledWith(
88
- 2,
89
- expect.objectContaining({ data: expected, loading: false }),
90
- );
91
- });
92
-
93
- test('it should return method to fetch next page', async () => {
94
- const callback = jest.fn();
95
- client.http.get = jest
96
- .fn()
97
- .mockResolvedValue(channelUserQueryResponse)
98
- .mockResolvedValueOnce(channelUserQueryResponsePage2);
99
-
100
- getMembers({ channelId }, callback);
101
- await pause();
102
-
103
- expect(callback).toHaveBeenCalled();
104
- expect(callback.mock.lastCall).toHaveLength(1);
105
-
106
- const { onNextPage, hasNextPage } = callback.mock.lastCall[0];
107
-
108
- expect(hasNextPage).toBe(true);
109
- expect(onNextPage).toBeTruthy();
110
-
111
- onNextPage();
112
- await pause();
113
-
114
- const payload = convertRawChannelPayload(channelUserQueryResponse.data);
115
- const payload2 = convertRawChannelPayload(channelUserQueryResponsePage2.data);
116
-
117
- const snapshot = getSnapshot();
118
- snapshot.loading = false;
119
- snapshot.data = [...payload2.channelUsers, ...payload.channelUsers];
120
-
121
- expect(callback).toHaveBeenNthCalledWith(4, expect.objectContaining(snapshot));
122
- });
123
-
124
62
  const events: [
125
63
  string,
126
64
  keyof Amity.Events,
@@ -59,37 +59,6 @@ describe('searchMembers', () => {
59
59
  );
60
60
  });
61
61
 
62
- const filters: [string, Amity.ChannelMembersLiveCollection, Amity.Membership<'channel'>[]][] = [
63
- [
64
- 'roles',
65
- { channelId, roles: channelUserQueryResponsePage3.data.channelUsers[0].roles },
66
- [channelUserWithRole],
67
- ],
68
- ['searched term', { channelId, search: 'use' }, [channelUserWithRole, bannedChannelUser]],
69
- ['member', { channelId, memberships: ['member'] }, [channelUserWithRole, mutedChannelUser]],
70
- ['muted members', { channelId, memberships: ['muted'] }, [mutedChannelUser]],
71
- ['banned members', { channelId, memberships: ['banned'] }, [bannedChannelUser]],
72
- [
73
- 'muted and banned members',
74
- { channelId, memberships: ['muted', 'banned'] },
75
- [mutedChannelUser, bannedChannelUser],
76
- ],
77
- ];
78
-
79
- test.each(filters)('it should filter channelUsers by %s', async (filter, params, expected) => {
80
- const callback = jest.fn();
81
- client.http.get = jest.fn().mockResolvedValue(channelUserQueryResponsePage3);
82
-
83
- searchMembers(params, callback);
84
- await pause();
85
-
86
- expect(callback).toHaveBeenNthCalledWith(1, expect.objectContaining(getSnapshot()));
87
- expect(callback).toHaveBeenNthCalledWith(
88
- 2,
89
- expect.objectContaining({ data: expected, loading: false }),
90
- );
91
- });
92
-
93
62
  test('it should return method to fetch next page', async () => {
94
63
  const callback = jest.fn();
95
64
  client.http.get = jest
@@ -70,14 +70,8 @@ export const getMembers = (
70
70
  const disposers: Amity.Unsubscriber[] = [];
71
71
  const cacheKey = ['communityUsers', 'collection', { communityId: params.communityId }];
72
72
 
73
- const responder = (data: Amity.CommunityMemberLiveCollectionCache) => {
74
- let communityMembers: Amity.Membership<'community'>[] =
75
- data.data
76
- .map(id => pullFromCache<Amity.Membership<'community'>>(['communityUsers', 'get', id])!)
77
- .filter(Boolean)
78
- .map(({ data }) => data) ?? [];
79
-
80
- communityMembers = filterByPropIntersection(communityMembers, 'roles', params.roles);
73
+ const applyFilter = <T extends Amity.Membership<'community'>>(data: T[]): T[] => {
74
+ let communityMembers = filterByPropIntersection(data, 'roles', params.roles);
81
75
 
82
76
  if (params.membership) {
83
77
  communityMembers = communityMembers.filter(({ communityMembership }) =>
@@ -95,9 +89,19 @@ export const getMembers = (
95
89
  sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated,
96
90
  );
97
91
 
92
+ return communityMembers;
93
+ };
94
+
95
+ const responder = (data: Amity.CommunityMemberLiveCollectionCache, isEventModel = false) => {
96
+ const communityMembers: Amity.Membership<'community'>[] =
97
+ data.data
98
+ .map(id => pullFromCache<Amity.Membership<'community'>>(['communityUsers', 'get', id])!)
99
+ .filter(Boolean)
100
+ .map(({ data }) => data) ?? [];
101
+
98
102
  callback({
99
103
  onNextPage: onFetch,
100
- data: communityMembers,
104
+ data: isEventModel ? applyFilter(communityMembers) : communityMembers,
101
105
  hasNextPage: !!data.params?.page,
102
106
  loading: data.loading,
103
107
  error: data.error,
@@ -122,7 +126,7 @@ export const getMembers = (
122
126
  collection.data = [...new Set([communityMemberCacheId, ...collection.data])];
123
127
 
124
128
  pushToCache(cacheKey, collection);
125
- responder(collection);
129
+ responder(collection, true);
126
130
  };
127
131
 
128
132
  const onFetch = (initial = false) => {
@@ -50,37 +50,11 @@ describe('getMembers', () => {
50
50
  expect(callback).toHaveBeenNthCalledWith(
51
51
  2,
52
52
  expect.objectContaining(
53
- getSnapshot({ data: [convertedCommunityUser2, convertedCommunityUser1], loading: false }),
53
+ getSnapshot({ data: [convertedCommunityUser1, convertedCommunityUser2], loading: false }),
54
54
  ),
55
55
  );
56
56
  });
57
57
 
58
- const filters: [string, Amity.CommunityMemberLiveCollection, Amity.Membership<'community'>[]][] =
59
- [
60
- ['roles', { communityId, roles: ['test-role'] }, [withRoleCommunityUser]],
61
- [
62
- 'searched term',
63
- { communityId, search: 'use' },
64
- [withRoleCommunityUser, bannedCommunityUser],
65
- ],
66
- ['member', { communityId, membership: ['member'] }, [withRoleCommunityUser]],
67
- ['banned members', { communityId, membership: ['banned'] }, [bannedCommunityUser]],
68
- ];
69
-
70
- test.each(filters)('it should filter channelUsers by %s', async (filter, params, expected) => {
71
- const callback = jest.fn();
72
- client.http.get = jest.fn().mockResolvedValue(communityUserQueryResponsePage2);
73
-
74
- getMembers(params, callback);
75
- await pause();
76
-
77
- expect(callback).toHaveBeenNthCalledWith(1, expect.objectContaining(getSnapshot()));
78
- expect(callback).toHaveBeenNthCalledWith(
79
- 2,
80
- expect.objectContaining({ data: expected, loading: false }),
81
- );
82
- });
83
-
84
58
  test('it should return method to fetch next page', async () => {
85
59
  const callback = jest.fn();
86
60
  client.http.get = jest
@@ -6,12 +6,12 @@ import { ASCError, ASCUnknownError } from '~/core/errors';
6
6
  const QOS_FAILURE_CODE = 128;
7
7
 
8
8
  const RETRY_BASE_TIMEOUT = 1000;
9
- const RETRY_COUNT_MAX = 10;
9
+ const RETRY_MAX_TIMEOUT = 8000;
10
10
 
11
11
  const enum MqttError {
12
12
  IDENTIFIER_REJECTED = 2,
13
- BAD_USERNAME_OR_PASSWORD = 4,
14
- NOT_AUTHORIZED = 5,
13
+ BAD_USERNAME_OR_PASSWORD = 134,
14
+ NOT_AUTHORIZED = 135,
15
15
  }
16
16
 
17
17
  export function getMqttOptions(params: {
@@ -23,8 +23,8 @@ export function getMqttOptions(params: {
23
23
  clean: false, // keep subscriptions
24
24
  clientId: `mqttjs_ + ${Math.random().toString(16).substring(2, 10)}`,
25
25
  protocolId: 'MQTT',
26
- protocolVersion: 4,
27
- reconnectPeriod: 0, // disable auto reconnect
26
+ protocolVersion: 5,
27
+ reconnectPeriod: RETRY_BASE_TIMEOUT,
28
28
  will: {
29
29
  topic: 'WillMsg',
30
30
  payload: 'Connection Closed abnormally..!',
@@ -47,16 +47,7 @@ export function getMqttOptions(params: {
47
47
  * @hidden
48
48
  */
49
49
  export const createMqttTransport = (endpoint: string): Amity.MqttClient => {
50
- let mqttClient: MqttClient | void;
51
- let retryCount = 0;
52
- let allowReconnection = true;
53
-
54
- const reconnect = () => {
55
- setTimeout(() => {
56
- retryCount += 1;
57
- mqttClient!.reconnect();
58
- }, RETRY_BASE_TIMEOUT * 2 ** (retryCount > RETRY_COUNT_MAX ? RETRY_COUNT_MAX : retryCount));
59
- };
50
+ let mqttClient: MqttClient;
60
51
 
61
52
  async function connect(params: { accessToken: string; userId: string }): Promise<void> {
62
53
  if (mqttClient) {
@@ -70,8 +61,7 @@ export const createMqttTransport = (endpoint: string): Amity.MqttClient => {
70
61
  );
71
62
 
72
63
  mqttClient.on('connect', () => {
73
- retryCount = 0;
74
- allowReconnection = true;
64
+ mqttClient.options.reconnectPeriod = RETRY_BASE_TIMEOUT;
75
65
  });
76
66
 
77
67
  mqttClient.on('error', (error: Error & { code: number }) => {
@@ -80,14 +70,16 @@ export const createMqttTransport = (endpoint: string): Amity.MqttClient => {
80
70
  case MqttError.IDENTIFIER_REJECTED:
81
71
  case MqttError.BAD_USERNAME_OR_PASSWORD:
82
72
  case MqttError.NOT_AUTHORIZED:
83
- allowReconnection = false;
73
+ mqttClient.end();
84
74
  }
85
75
  });
86
76
 
87
- mqttClient.on('close', () => {
88
- if (allowReconnection) {
89
- reconnect();
90
- }
77
+ mqttClient.on('reconnect', () => {
78
+ // Double the reconnect period for each attempt
79
+ mqttClient.options.reconnectPeriod = Math.min(
80
+ (mqttClient.options.reconnectPeriod || RETRY_BASE_TIMEOUT) * 2,
81
+ RETRY_MAX_TIMEOUT,
82
+ );
91
83
  });
92
84
 
93
85
  return new Promise(resolve => mqttClient!.once('connect', () => resolve()));
@@ -96,8 +88,6 @@ export const createMqttTransport = (endpoint: string): Amity.MqttClient => {
96
88
  return {
97
89
  connect,
98
90
  async disconnect(): Promise<void> {
99
- allowReconnection = false;
100
-
101
91
  if (this.connected) {
102
92
  return new Promise(resolve => mqttClient?.end(true, undefined, () => resolve()));
103
93
  }
@@ -69,14 +69,8 @@ export const getUsers = (
69
69
  const disposers: Amity.Unsubscriber[] = [];
70
70
  const cacheKey = ['user', 'collection', {}];
71
71
 
72
- const responder = (data: Amity.UserLiveCollectionCache) => {
73
- let users: Amity.User[] =
74
- data.data
75
- .map(userId => pullFromCache<Amity.User>(['user', 'get', userId])!)
76
- .filter(Boolean)
77
- .map(({ data }) => data) ?? [];
78
-
79
- users = filterByPropEquality(users, 'displayName', params.displayName);
72
+ const applyFilter = (data: Amity.User[]): Amity.User[] => {
73
+ let users = filterByPropEquality(data, 'displayName', params.displayName);
80
74
 
81
75
  switch (params.sortBy) {
82
76
  case 'firstCreated':
@@ -95,9 +89,22 @@ export const getUsers = (
95
89
  .sort(sortByDisplayName);
96
90
  }
97
91
 
92
+ return users;
93
+ };
94
+
95
+ const responder = (data: Amity.UserLiveCollectionCache, isEventModel = false) => {
96
+ const users: Amity.User[] =
97
+ data.data
98
+ .map(userId => pullFromCache<Amity.User>(['user', 'get', userId])!)
99
+ .filter(Boolean)
100
+ .map(({ data }) => data) ?? [];
101
+
98
102
  callback({
99
103
  onNextPage: onFetch,
100
- data: users,
104
+ /*
105
+ * Only apply filter to RTE Model
106
+ */
107
+ data: isEventModel ? applyFilter(users) : users,
101
108
  hasNextPage: !!data.params?.page,
102
109
  loading: data.loading,
103
110
  error: data.error,
@@ -111,7 +118,7 @@ export const getUsers = (
111
118
  collection.data = [...new Set([user.userId, ...collection.data])];
112
119
 
113
120
  pushToCache(cacheKey, collection);
114
- responder(collection);
121
+ responder(collection, true);
115
122
  };
116
123
 
117
124
  const onFetch = (initial = false) => {
@@ -6,7 +6,6 @@ import {
6
6
  pause,
7
7
  user11,
8
8
  user12,
9
- user21,
10
9
  userQueryResponse,
11
10
  userQueryResponsePage2,
12
11
  } from '~/utils/tests';
@@ -114,6 +113,7 @@ describe('getUsers', () => {
114
113
  });
115
114
 
116
115
  describe('events', () => {
116
+ // integration_test_id: 60b4b354-efca-49bc-aa8b-d63a8da6ef31
117
117
  const updatedUser = { ...user11, displayName: 'updated-user' };
118
118
  const flaggedUser = { ...user11, flagCount: 1 };
119
119
  const unflaggedUser = { ...user11, flagCount: 1 };
@@ -167,32 +167,4 @@ describe('getUsers', () => {
167
167
  );
168
168
  });
169
169
  });
170
-
171
- // integration_test_id: 60b4b354-efca-49bc-aa8b-d63a8da6ef31
172
- const filters: [string, Amity.UserLiveCollection, Amity.User[]][] = [
173
- ['displayName', { displayName: 'displayName' }, [user21]],
174
- ];
175
-
176
- test.each(filters)('it should filter by %s communities', async (filter, params, expected) => {
177
- const callback = jest.fn();
178
- client.http.get = jest.fn().mockResolvedValue(userQueryResponsePage2);
179
-
180
- getUsers(params, callback);
181
-
182
- expect(callback).toHaveBeenCalledTimes(1);
183
- // check if cache data returned (should be empty)
184
- expect(callback).toHaveBeenCalledWith(expect.objectContaining(getSnapshot()));
185
-
186
- await pause();
187
-
188
- expect(callback).toHaveBeenCalledTimes(2);
189
- expect(callback).toHaveBeenCalledWith(
190
- expect.objectContaining(
191
- getSnapshot({
192
- loading: false,
193
- data: expected,
194
- }),
195
- ),
196
- );
197
- });
198
170
  });