@amityco/ts-sdk-react-native 6.8.2-d546836.0 → 6.8.3-6df654f.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":"onMessageMarked.d.ts","sourceRoot":"","sources":["../../../src/marker/events/onMessageMarked.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,aAChB,MAAM,QAAQ,CAAC,MAAM,aAAa,CAAC,KAC5C,MAAM,YAiDR,CAAC"}
1
+ {"version":3,"file":"onMessageMarked.d.ts","sourceRoot":"","sources":["../../../src/marker/events/onMessageMarked.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,aAChB,MAAM,QAAQ,CAAC,MAAM,aAAa,CAAC,KAC5C,MAAM,YAwDR,CAAC"}
@@ -1,3 +1,4 @@
1
+ export declare const applyFilter: <T extends Amity.Message<any>>(data: T[], params: Amity.MessagesLiveCollection) => T[];
1
2
  /**
2
3
  * ```js
3
4
  * import { getMessages } from '@amityco/ts-sdk-react-native';
@@ -1 +1 @@
1
- {"version":3,"file":"getMessages.d.ts","sourceRoot":"","sources":["../../../src/messageRepository/observers/getMessages.ts"],"names":[],"mappings":"AAgCA;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,WAAW,WACd,MAAM,sBAAsB,YAC1B,MAAM,sBAAsB,CAAC,MAAM,OAAO,CAAC,WAC5C,MAAM,oBAAoB,KAClC,MAAM,YAkHR,CAAC"}
1
+ {"version":3,"file":"getMessages.d.ts","sourceRoot":"","sources":["../../../src/messageRepository/observers/getMessages.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,WAAW,oDAEd,MAAM,sBAAsB,QA2CrC,CAAC;AAKF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,WAAW,WACd,MAAM,sBAAsB,YAC1B,MAAM,sBAAsB,CAAC,MAAM,OAAO,CAAC,WAC5C,MAAM,oBAAoB,KAClC,MAAM,YA2HR,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getUsers.d.ts","sourceRoot":"","sources":["../../../src/userRepository/observers/getUsers.ts"],"names":[],"mappings":"AAkCA,eAAO,MAAM,WAAW,4CAEd,MAAM,kBAAkB,QAsBjC,CAAC;AAKF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,QAAQ,WACX,MAAM,kBAAkB,YACtB,MAAM,sBAAsB,CAAC,MAAM,IAAI,CAAC,WACzC,MAAM,oBAAoB,eAiGpC,CAAC"}
1
+ {"version":3,"file":"getUsers.d.ts","sourceRoot":"","sources":["../../../src/userRepository/observers/getUsers.ts"],"names":[],"mappings":"AAmCA,eAAO,MAAM,WAAW,4CAEd,MAAM,kBAAkB,QAsBjC,CAAC;AAKF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,QAAQ,WACX,MAAM,kBAAkB,YACtB,MAAM,sBAAsB,CAAC,MAAM,IAAI,CAAC,WACzC,MAAM,oBAAoB,eAiGpC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amityco/ts-sdk-react-native",
3
- "version": "6.8.2-d546836.0",
3
+ "version": "6.8.3-6df654f.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",
@@ -66,6 +66,7 @@ declare global {
66
66
  deliveredCount: number;
67
67
  referenceId?: string;
68
68
  } & Amity.Content<T> &
69
+ Amity.Flaggable &
69
70
  Amity.Mentionable<'user' | 'channel'> &
70
71
  Amity.Metadata &
71
72
  Amity.Reactable &
@@ -29,7 +29,11 @@ import { removeChannelMarkerCache } from '../utils/removeChannelMarkerCache';
29
29
  * than the one already connected, in which case the existing subscriptions need
30
30
  * to be cleared
31
31
  */
32
- const subscriptions: Amity.Unsubscriber[] = [];
32
+ let subscriptions: Amity.Unsubscriber[] = [];
33
+
34
+ async function runMqtt() {
35
+ await modifyMqttConnection();
36
+ }
33
37
 
34
38
  /* begin_public_function
35
39
  id: client.login
@@ -74,6 +78,7 @@ export const login = async (
74
78
 
75
79
  // Remove subscription to ban and delete
76
80
  subscriptions.forEach(fn => fn());
81
+ subscriptions = [];
77
82
  }
78
83
 
79
84
  // default values
@@ -88,10 +93,7 @@ export const login = async (
88
93
  // wire websocket events to our event emitter
89
94
  proxyWebsocketEvents(client.ws, client.emitter);
90
95
 
91
- // TODO: in phase 2, this should not be necessary. we should have WS
92
- // to be connected "on demand" rather than "by default"
93
- await new Promise(resolve => {
94
- client.ws.once('connect', resolve);
96
+ client.ws.once('connect', () => {
95
97
  client.ws.open();
96
98
  });
97
99
 
@@ -122,54 +124,56 @@ export const login = async (
122
124
  }
123
125
 
124
126
  if (config?.disableRTE !== true) {
125
- await modifyMqttConnection();
127
+ runMqtt();
126
128
  }
127
129
 
128
- subscriptions.push(
129
- // GLOBAL_BAN
130
- onClientBanned((_: Amity.UserPayload) => {
131
- terminateClient(Amity.TokenTerminationReason.GLOBAL_BAN);
130
+ if (subscriptions.length === 0) {
131
+ subscriptions.push(
132
+ // GLOBAL_BAN
133
+ onClientBanned((_: Amity.UserPayload) => {
134
+ terminateClient(Amity.TokenTerminationReason.GLOBAL_BAN);
132
135
 
133
- subscriptions.forEach(fn => fn());
136
+ subscriptions.forEach(fn => fn());
134
137
 
135
- unsubWatcher();
136
- }),
138
+ unsubWatcher();
139
+ }),
137
140
 
138
- onTokenTerminated(_ => {
139
- terminateClient();
141
+ onTokenTerminated(_ => {
142
+ terminateClient();
140
143
 
141
- subscriptions.forEach(fn => fn());
144
+ subscriptions.forEach(fn => fn());
142
145
 
143
- unsubWatcher();
144
- }),
146
+ unsubWatcher();
147
+ }),
145
148
 
146
- onUserDeleted((user: Amity.User) => {
147
- if (user.userId === client.userId) {
148
- terminateClient(Amity.TokenTerminationReason.USER_DELETED);
149
+ onUserDeleted((user: Amity.User) => {
150
+ if (user.userId === client.userId) {
151
+ terminateClient(Amity.TokenTerminationReason.USER_DELETED);
149
152
 
150
- subscriptions.forEach(fn => fn());
153
+ subscriptions.forEach(fn => fn());
151
154
 
152
- unsubWatcher();
153
- }
154
- }),
155
+ unsubWatcher();
156
+ }
157
+ }),
155
158
 
156
- onTokenExpired(state => {
157
- setSessionState(state);
159
+ onTokenExpired(state => {
160
+ setSessionState(state);
158
161
 
159
- logout();
162
+ logout();
160
163
 
161
- subscriptions.forEach(fn => fn());
162
- }),
164
+ subscriptions.forEach(fn => fn());
165
+ }),
163
166
 
164
- // NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
165
- // the channel because currently backend can't handle this, so every time a user is banned from
166
- // a channel or the channel is deleted the channel's unread count will not be reset to zero
167
- onChannelDeleted(removeChannelMarkerCache),
168
- onChannelMemberBanned(removeChannelMarkerCache),
167
+ // NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
168
+ // the channel because currently backend can't handle this, so every time a user is banned from
169
+ // a channel or the channel is deleted the channel's unread count will not be reset to zero
170
+ onChannelDeleted(removeChannelMarkerCache),
171
+ onChannelMemberBanned(removeChannelMarkerCache),
169
172
 
170
- markReadEngineOnLoginHandler(),
171
- );
173
+ markReadEngineOnLoginHandler(),
174
+ );
175
+ }
172
176
 
173
- return client.ws.connected;
177
+ return true;
174
178
  };
175
179
  /* end_public_function */
@@ -109,9 +109,11 @@ export const getComments = (
109
109
  if (
110
110
  params.referenceId !== comment.referenceId ||
111
111
  params.referenceType !== comment.referenceType ||
112
+ params.parentId !== comment.parentId ||
112
113
  !collection
113
- )
114
+ ) {
114
115
  return;
116
+ }
115
117
 
116
118
  if (action === 'onCreate') {
117
119
  collection.data = [...new Set([comment.commentId, ...collection.data])];
package/src/index.ts CHANGED
@@ -43,6 +43,3 @@ export * as PollRepository from './pollRepository';
43
43
 
44
44
  // // external apis
45
45
  export * from './external/api';
46
-
47
- // Token and MQTTClientID
48
- export * from './core/device';
@@ -28,32 +28,39 @@ export const onMessageMarked = (
28
28
  ingestInCache(payload);
29
29
 
30
30
  const cacheCollection = queryCache<Amity.MessageLiveCollectionCache>(['message', 'collection']);
31
+ const { contentMarkers, feedMarkers } = payload;
31
32
 
32
- if (cacheCollection && cacheCollection?.length > 0) {
33
- const contentMarker = payload.contentMarkers[0];
33
+ if (cacheCollection && cacheCollection?.length > 0 && feedMarkers?.length > 0) {
34
+ /**
35
+ * in case of read the message collection,
36
+ * use feedId of the feedMarkers to check if it equal to subChannelId.
37
+ */
34
38
  const currentMessageCollection = cacheCollection.filter(currentMessage => {
35
- if (!isObject(currentMessage.key[2])) return false;
36
- return currentMessage.key[2].subChannelId === contentMarker.feedId;
39
+ const cacheKey = currentMessage.key;
40
+ if (!isObject(cacheKey[2])) return false;
41
+
42
+ const queryParams = cacheKey[2] as Amity.MessagesLiveCollection;
43
+ return queryParams.subChannelId === feedMarkers[0].feedId;
37
44
  });
38
45
 
39
- if (currentMessageCollection.length > 0) {
46
+ if (currentMessageCollection.length > 0 && contentMarkers?.length > 0) {
40
47
  const currentMessages =
41
48
  currentMessageCollection[0].data?.data?.map(messageId => {
42
49
  return pullFromCache<Amity.Message>(['message', 'get', messageId]);
43
50
  }) || [];
44
51
 
45
52
  currentMessages.forEach(message => {
46
- const isSameSubChannelId = contentMarker.feedId === message?.data.subChannelId;
47
- const isReadCountLatest = contentMarker.readCount > message?.data.readCount!;
53
+ const isSameSubChannelId = contentMarkers[0].feedId === message?.data.subChannelId;
54
+ const isReadCountLatest = contentMarkers[0].readCount > message?.data.readCount!;
48
55
  const isDeliveredCountLatest =
49
- contentMarker.deliveredCount > message?.data.deliveredCount!;
56
+ contentMarkers[0]?.deliveredCount > message?.data.deliveredCount!;
50
57
 
51
58
  if (isSameSubChannelId) {
52
59
  pushToCache(['message', 'get', message.data.messageId], {
53
60
  ...message.data,
54
- readCount: isReadCountLatest ? contentMarker.readCount : message?.data.readCount!,
61
+ readCount: isReadCountLatest ? contentMarkers[0].readCount : message?.data.readCount!,
55
62
  deliveredCount: isDeliveredCountLatest
56
- ? contentMarker.deliveredCount
63
+ ? contentMarkers[0].deliveredCount
57
64
  : message?.data.deliveredCount!,
58
65
  });
59
66
  }
@@ -27,6 +27,57 @@ import {
27
27
  import { onMessageFetched } from '../events/onMessageFetched';
28
28
  import { queryMessages } from '../api/queryMessages';
29
29
 
30
+ /*
31
+ * Exported for testing
32
+ * @hidden
33
+ */
34
+ export const applyFilter = <T extends Amity.Message>(
35
+ data: T[],
36
+ params: Amity.MessagesLiveCollection,
37
+ ): T[] => {
38
+ let messages = data;
39
+
40
+ messages = messages.filter(m => {
41
+ if (params.tags) {
42
+ return params.tags.find(value => {
43
+ if (!m.tags) return false;
44
+ return m.tags.includes(value);
45
+ });
46
+ }
47
+ return true;
48
+ });
49
+
50
+ messages = messages.filter(m => {
51
+ if (params.excludeTags) {
52
+ return (params.excludeTags || []).find(value => {
53
+ if (!m.tags) return true;
54
+ return !m.tags.includes(value);
55
+ });
56
+ }
57
+ return true;
58
+ });
59
+
60
+ /*
61
+ * for cases when message is deleted via RTE, this flag is used to get
62
+ * items from cache that are !deleted
63
+ */
64
+ if (!params.includeDeleted) {
65
+ messages = filterByPropEquality(messages, 'isDeleted', false);
66
+ }
67
+
68
+ messages = messages.sort((message1, message2) => {
69
+ if (params.sortBy === 'segmentAsc') {
70
+ return message1.channelSegment - message2.channelSegment;
71
+ }
72
+ if (params.sortBy === 'segmentDesc') {
73
+ return message2.channelSegment - message1.channelSegment;
74
+ }
75
+ return 0;
76
+ });
77
+
78
+ return messages;
79
+ };
80
+
30
81
  /* begin_public_function
31
82
  id: message.query
32
83
  */
@@ -69,29 +120,17 @@ export const getMessages = (
69
120
  const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config ?? {};
70
121
 
71
122
  const disposers: Amity.Unsubscriber[] = [];
72
- const cacheKey = ['message', 'collection', params, uuid()];
123
+ const uniqueId = uuid();
124
+ const cacheKey = ['message', 'collection', params, uniqueId];
73
125
 
74
126
  const responder = (data: Amity.MessageLiveCollectionCache) => {
75
- let messages: Amity.Message[] =
127
+ const messages: Amity.Message[] = applyFilter(
76
128
  data.data
77
129
  .map(messageId => pullFromCache<Amity.Message>(['message', 'get', messageId])!)
78
130
  .filter(Boolean)
79
- .filter(item => {
80
- if (!params.tags) return true;
81
- return params.tags.find(value => {
82
- if (!item.data?.tags) return false;
83
- return item.data.tags.includes(value);
84
- });
85
- })
86
- .map(({ data }) => data) ?? [];
87
-
88
- /*
89
- * for cases when message is deleted via RTE, this flag is used to get
90
- * items from cache that are !deleted
91
- */
92
- if (!params.includeDeleted) {
93
- messages = filterByPropEquality(messages, 'isDeleted', false);
94
- }
131
+ .map(({ data }) => data) ?? [],
132
+ params,
133
+ );
95
134
 
96
135
  callback({
97
136
  onNextPage: onFetch,
@@ -107,6 +146,28 @@ export const getMessages = (
107
146
 
108
147
  if (params.subChannelId !== message?.subChannelId || !collection) return;
109
148
 
149
+ // /*
150
+ // * check if RTE message event payload is with the params in order to update in the colleciton cache
151
+ // */
152
+
153
+ if (params.dataType && params.dataType !== message.dataType) return;
154
+
155
+ if (params.excludeTags && params.excludeTags?.some(value => message.tags?.includes(value)))
156
+ return;
157
+
158
+ if (!!params.hasFlags !== !!message.flagCount) return;
159
+
160
+ if (params.parentId && params.parentId !== message.parentId) return;
161
+
162
+ if (params.hasOwnProperty('includeDeleted') && !params.includeDeleted && message.isDeleted)
163
+ return;
164
+
165
+ if (params.tags && !params.tags?.some(value => message.tags?.includes(value))) return;
166
+
167
+ if (!collection.data.includes(message.messageId) && action === 'onCreate') {
168
+ collection.data = [...new Set([message.messageId, ...collection.data])];
169
+ }
170
+
110
171
  pushToCache(cacheKey, collection);
111
172
 
112
173
  responder(collection);
@@ -114,7 +175,6 @@ export const getMessages = (
114
175
 
115
176
  const onFetch = (initial = false) => {
116
177
  const collection = pullFromCache<Amity.MessageLiveCollectionCache>(cacheKey)?.data;
117
-
118
178
  const messages = collection?.data ?? [];
119
179
 
120
180
  if (!initial && messages.length > 0 && !collection?.params?.page) return;
@@ -2,6 +2,7 @@
2
2
  import { getResolver } from '~/core/model';
3
3
  import { pullFromCache, pushToCache } from '~/cache/api';
4
4
  import { getActiveClient } from '~/client/api';
5
+ import { uuid } from '~/core/uuid';
5
6
 
6
7
  import {
7
8
  createQuery,
@@ -98,7 +99,7 @@ export const getUsers = (
98
99
  const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config ?? {};
99
100
 
100
101
  const disposers: Amity.Unsubscriber[] = [];
101
- const cacheKey = ['user', 'collection', queryParams as Amity.Serializable];
102
+ const cacheKey = ['user', 'collection', uuid()];
102
103
 
103
104
  const responder = (data: Amity.UserLiveCollectionCache, isEventModel = false) => {
104
105
  const users: Amity.User[] =
@@ -59,7 +59,11 @@ describe('getUsers', () => {
59
59
  );
60
60
  });
61
61
 
62
- test('it should return data from cache', async () => {
62
+ test.skip('it should return data from cache', async () => {
63
+ /**
64
+ * skip this unit test because the behaviour is changed.
65
+ * when calling getUsers(), it will create a new instance of the user collection.
66
+ */
63
67
  const callback = jest.fn();
64
68
  client.http.get = jest.fn().mockResolvedValue(userQueryResponse);
65
69