@amityco/ts-sdk 0.0.1-beta.43.1 → 0.0.1-beta.45.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.
- package/dist/category/api/queryCategories.d.ts.map +1 -1
- package/dist/comment/api/queryComments.d.ts.map +1 -1
- package/dist/community/api/queryCommunities.d.ts.map +1 -1
- package/dist/core/query/filtering.d.ts +10 -0
- package/dist/core/query/filtering.d.ts.map +1 -1
- package/dist/index.cjs.js +136 -114
- package/dist/index.esm.js +136 -115
- package/dist/index.umd.js +4 -4
- package/dist/message/api/queryMessages.d.ts +1 -17
- package/dist/message/api/queryMessages.d.ts.map +1 -1
- package/dist/message/utils/prepareMessagePayload.d.ts.map +1 -1
- package/dist/post/api/queryPosts.d.ts.map +1 -1
- package/dist/post/observers/livePosts.d.ts.map +1 -1
- package/dist/subChannel/api/querySubChannels.d.ts.map +1 -1
- package/dist/utils/inferIsDeleted.d.ts +2 -0
- package/dist/utils/inferIsDeleted.d.ts.map +1 -0
- package/dist/utils/tests/inferIsDeleted.test.d.ts +2 -0
- package/dist/utils/tests/inferIsDeleted.test.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/category/api/queryCategories.ts +3 -1
- package/src/category/observers/liveCategories.ts +5 -5
- package/src/category/observers/tests/liveCategories.test.ts +7 -5
- package/src/channel/api/tests/removeChannelMembers.test.ts +3 -4
- package/src/channel/observers/liveChannelMembers.ts +4 -4
- package/src/channel/observers/liveChannels.ts +4 -4
- package/src/channel/observers/tests/liveChannels.test.ts +9 -15
- package/src/client/api/connectClient.ts +1 -1
- package/src/comment/api/queryComments.ts +3 -1
- package/src/comment/observers/liveComments.ts +5 -5
- package/src/community/api/queryCommunities.ts +2 -1
- package/src/community/api/test/queryCommunity.test.ts +2 -2
- package/src/community/observers/liveCommunities.ts +5 -5
- package/src/community/observers/liveCommunityMembers.ts +4 -4
- package/src/community/observers/tests/liveCommunities.test.ts +7 -7
- package/src/core/query/filtering.ts +38 -0
- package/src/follow/observers/liveFollowers.ts +4 -4
- package/src/follow/observers/liveFollowings.ts +4 -4
- package/src/message/api/queryMessages.ts +15 -50
- package/src/message/api/tests/queryMessages.test.ts +2 -37
- package/src/message/observers/liveMessages.ts +7 -7
- package/src/message/tests/observers/liveMessage.test.ts +1 -1
- package/src/message/tests/observers/liveMessages.test.ts +1 -1
- package/src/message/utils/prepareMessagePayload.ts +3 -1
- package/src/post/api/queryPosts.ts +3 -1
- package/src/post/observers/livePosts.ts +11 -6
- package/src/post/observers/tests/livePosts.test.ts +10 -4
- package/src/reaction/observers/liveReactions.ts +4 -4
- package/src/subChannel/api/querySubChannels.ts +3 -1
- package/src/subChannel/observers/liveSubChannels.ts +1 -1
- package/src/user/observers/liveUsers.ts +4 -4
- package/src/user/observers/tests/liveUsers.test.ts +3 -9
- package/src/utils/inferIsDeleted.ts +16 -0
- package/src/utils/tests/inferIsDeleted.test.ts +15 -0
|
@@ -2,7 +2,9 @@ import { getActiveClient } from '~/client/api';
|
|
|
2
2
|
|
|
3
3
|
import { fireEvent } from '~/core/events';
|
|
4
4
|
import { toPageRaw } from '~/core/query';
|
|
5
|
-
import {
|
|
5
|
+
import { pushToCache } from '~/cache/api';
|
|
6
|
+
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
7
|
+
import { getResolver } from '~/core/model';
|
|
6
8
|
import { convertQueryParams, prepareMessagePayload } from '../utils';
|
|
7
9
|
|
|
8
10
|
/* begin_public_function
|
|
@@ -47,12 +49,18 @@ export const queryMessages = async (
|
|
|
47
49
|
|
|
48
50
|
const cachedAt = client.cache && Date.now();
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
if (client.cache) {
|
|
53
|
+
/*
|
|
54
|
+
* queryMessages.locally is unsupported for messages as message list updates
|
|
55
|
+
* frequently and leads to bugs when user switches between channels, i.e. when
|
|
56
|
+
* the public function (live messages) calls unmount. The list fetched on
|
|
57
|
+
* after from the cache is stale.
|
|
58
|
+
*/
|
|
59
|
+
ingestInCache(data, { cachedAt });
|
|
60
|
+
|
|
61
|
+
const cacheKey = ['message', 'query', params as Amity.Serializable];
|
|
62
|
+
pushToCache(cacheKey, { messages: messages.map(getResolver('message')), paging });
|
|
63
|
+
}
|
|
56
64
|
|
|
57
65
|
fireEvent('local.message.fetched', { messages });
|
|
58
66
|
|
|
@@ -62,46 +70,3 @@ export const queryMessages = async (
|
|
|
62
70
|
return { data: messages, cachedAt, prevPage, nextPage };
|
|
63
71
|
};
|
|
64
72
|
/* end_public_function */
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* ```js
|
|
68
|
-
* import { queryMessages } from '@amityco/ts-sdk'
|
|
69
|
-
* const messages = queryMessages.locally!({ channelId })
|
|
70
|
-
* ```
|
|
71
|
-
*
|
|
72
|
-
* Queries a paginable list of {@link Amity.Message} objects from cache
|
|
73
|
-
*
|
|
74
|
-
* @param query The query parameters
|
|
75
|
-
* @returns A page of {@link Amity.Message} objects
|
|
76
|
-
*
|
|
77
|
-
* @category Message API
|
|
78
|
-
*/
|
|
79
|
-
queryMessages.locally = (
|
|
80
|
-
query: Parameters<typeof queryMessages>[0],
|
|
81
|
-
): Amity.Cached<Amity.Paged<Amity.Message, Amity.Page<string>>> | undefined => {
|
|
82
|
-
const client = getActiveClient();
|
|
83
|
-
client.log('message/queryMessages.locally', query);
|
|
84
|
-
|
|
85
|
-
if (!client.cache) return;
|
|
86
|
-
|
|
87
|
-
const params = convertQueryParams(query);
|
|
88
|
-
|
|
89
|
-
const queryKey = ['message', 'query', params as Amity.Serializable];
|
|
90
|
-
const { data, cachedAt } =
|
|
91
|
-
pullFromCache<{ messages: Pick<Amity.Message, 'messageId'>[] } & Amity.Pagination>(queryKey) ??
|
|
92
|
-
{};
|
|
93
|
-
|
|
94
|
-
if (!data?.messages.length) return;
|
|
95
|
-
|
|
96
|
-
const messages: Amity.Message[] = data.messages
|
|
97
|
-
.map(messageId => pullFromCache<Amity.Message>(['message', 'get', messageId])!)
|
|
98
|
-
.filter(Boolean)
|
|
99
|
-
.map(({ data }) => data);
|
|
100
|
-
|
|
101
|
-
const prevPage = toPageRaw(data?.paging.previous);
|
|
102
|
-
const nextPage = toPageRaw(data?.paging.next);
|
|
103
|
-
|
|
104
|
-
return messages.length === data?.messages?.length
|
|
105
|
-
? { data: messages, cachedAt, prevPage, nextPage }
|
|
106
|
-
: undefined;
|
|
107
|
-
};
|
|
@@ -106,48 +106,13 @@ describe('queryMessages', () => {
|
|
|
106
106
|
expect(mockFn.mock.lastCall[1].params.isDeleted).toBe(false);
|
|
107
107
|
});
|
|
108
108
|
|
|
109
|
-
test('it should set isDeleted to
|
|
109
|
+
test('it should set isDeleted to false if includeDeleted is undefined', async () => {
|
|
110
110
|
const mockFn = jest.fn();
|
|
111
111
|
client.http.get = mockFn.mockResolvedValue(getResolvedMessageValue());
|
|
112
112
|
|
|
113
113
|
await queryMessages(queryCriteriaWithoutPage);
|
|
114
114
|
|
|
115
115
|
expect(mockFn.mock.lastCall).toHaveLength(2);
|
|
116
|
-
expect(mockFn.mock.lastCall[1].params.isDeleted).
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
describe('queryMessages.locally', () => {
|
|
121
|
-
beforeEach(() => enableCache());
|
|
122
|
-
afterEach(() => disableCache());
|
|
123
|
-
|
|
124
|
-
test('should return cached messages', () => {
|
|
125
|
-
messagesToQuery.forEach(message => pushToCache(['message', 'get', message.messageId], message));
|
|
126
|
-
|
|
127
|
-
pushToCache(['message', 'query', convertQueryParams(queryCriteria)], {
|
|
128
|
-
messages: messageIds,
|
|
129
|
-
paging,
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
expect(queryMessages.locally(queryCriteria)).toEqual(
|
|
133
|
-
expect.objectContaining({
|
|
134
|
-
data: messagesToQuery,
|
|
135
|
-
prevPage: undefined,
|
|
136
|
-
nextPage,
|
|
137
|
-
}),
|
|
138
|
-
);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
test(`shouldn't return if individual message cache not exist`, () => {
|
|
142
|
-
pushToCache(['message', 'query', convertQueryParams(queryCriteria)], {
|
|
143
|
-
messages: messageIds,
|
|
144
|
-
paging,
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
expect(queryMessages.locally(queryCriteria)).toBeUndefined();
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
test('it should return undefined if message not in cache', () => {
|
|
151
|
-
expect(queryMessages.locally({ subChannelId: 'non-existent' })).toBeUndefined();
|
|
116
|
+
expect(mockFn.mock.lastCall[1].params.isDeleted).toBe(false);
|
|
152
117
|
});
|
|
153
118
|
});
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
onMessageUpdated,
|
|
23
23
|
} from '../events';
|
|
24
24
|
import { onMessageFetched } from '../events/onMessageFetched';
|
|
25
|
-
import { queryMessages } from '../api';
|
|
25
|
+
import { queryMessages } from '../api/queryMessages';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* ```js
|
|
@@ -76,7 +76,7 @@ export const liveMessages = (
|
|
|
76
76
|
* for cases when message is deleted via RTE, this flag is used to get
|
|
77
77
|
* items from cache that are !deleted
|
|
78
78
|
*/
|
|
79
|
-
if (params.includeDeleted
|
|
79
|
+
if (!params.includeDeleted) {
|
|
80
80
|
messages = filterByPropEquality(messages, 'isDeleted', false);
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -101,16 +101,16 @@ export const liveMessages = (
|
|
|
101
101
|
responder(collection);
|
|
102
102
|
};
|
|
103
103
|
|
|
104
|
-
const onFetch = () => {
|
|
104
|
+
const onFetch = (initial = false) => {
|
|
105
105
|
const collection = pullFromCache<Amity.MessageLiveCollectionCache>(cacheKey)?.data;
|
|
106
106
|
|
|
107
107
|
const messages = collection?.data ?? [];
|
|
108
108
|
|
|
109
|
-
if (messages.length > 0 && !collection?.params?.page) return;
|
|
109
|
+
if (!initial && messages.length > 0 && !collection?.params?.page) return;
|
|
110
110
|
|
|
111
111
|
const query = createQuery(queryMessages, {
|
|
112
112
|
...queryParams,
|
|
113
|
-
page: collection?.params
|
|
113
|
+
page: (!initial ? collection?.params.page : undefined) ?? { limit },
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
runQuery(
|
|
@@ -147,11 +147,11 @@ export const liveMessages = (
|
|
|
147
147
|
onMessageReactionRemoved(realtimeRouter('onReactionRemoved')),
|
|
148
148
|
);
|
|
149
149
|
|
|
150
|
-
onFetch();
|
|
150
|
+
onFetch(true);
|
|
151
|
+
disposers.push(() => dropFromCache(cacheKey));
|
|
151
152
|
|
|
152
153
|
return () => {
|
|
153
154
|
log(`liveMessages(tmpid: ${timestamp}) > dispose`);
|
|
154
155
|
disposers.forEach(fn => fn());
|
|
155
|
-
dropFromCache(cacheKey);
|
|
156
156
|
};
|
|
157
157
|
};
|
|
@@ -4,6 +4,8 @@ import { toToken } from '~/core/query';
|
|
|
4
4
|
import { getMessageMarkers } from '~/marker/api';
|
|
5
5
|
import { prepareMessagePayloadForCache } from '~/reaction/utils/prepareMessagePayloadForCache';
|
|
6
6
|
|
|
7
|
+
import { inferIsDeleted } from '~/utils/inferIsDeleted';
|
|
8
|
+
|
|
7
9
|
const getCachedMarker = (message: Amity.Message | Amity.RawMessage) => {
|
|
8
10
|
const key = {
|
|
9
11
|
creatorId: message.creatorId,
|
|
@@ -166,7 +168,7 @@ export function convertQueryParams({
|
|
|
166
168
|
const out: RawQueryMessages = {
|
|
167
169
|
...rest,
|
|
168
170
|
messageFeedId: subChannelId,
|
|
169
|
-
isDeleted: includeDeleted
|
|
171
|
+
isDeleted: inferIsDeleted(includeDeleted),
|
|
170
172
|
options: { token: toToken(page || { limit: 10 }, 'afterbeforeraw')! },
|
|
171
173
|
};
|
|
172
174
|
|
|
@@ -5,7 +5,9 @@ import { toToken, toPageRaw } from '~/core/query';
|
|
|
5
5
|
import { pullFromCache, pushToCache } from '~/cache/api';
|
|
6
6
|
import { ingestInCache } from '~/cache/api/ingestInCache';
|
|
7
7
|
import { getResolver } from '~/core/model';
|
|
8
|
+
|
|
8
9
|
import { prepareMembershipPayload } from '~/group/utils';
|
|
10
|
+
import { inferIsDeleted } from '~/utils/inferIsDeleted';
|
|
9
11
|
|
|
10
12
|
/* begin_public_function
|
|
11
13
|
id: post.query, feed.query.community_feed, feed.query.user_feed
|
|
@@ -39,7 +41,7 @@ export const queryPosts = async (
|
|
|
39
41
|
const { data } = await client.http.get<Amity.PostPayload & Amity.Pagination>(`/api/v4/posts`, {
|
|
40
42
|
params: {
|
|
41
43
|
...params,
|
|
42
|
-
isDeleted: includeDeleted
|
|
44
|
+
isDeleted: inferIsDeleted(includeDeleted),
|
|
43
45
|
/*
|
|
44
46
|
* when creating post like image, file, video BE will create 2 posts
|
|
45
47
|
* 1. parent post to store text with dataType=text
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
createQuery,
|
|
8
8
|
filterByFeedType,
|
|
9
9
|
filterByPropEquality,
|
|
10
|
+
filterByPostDataTypes,
|
|
10
11
|
queryOptions,
|
|
11
12
|
runQuery,
|
|
12
13
|
sortByFirstCreated,
|
|
@@ -89,7 +90,7 @@ export const livePosts = (
|
|
|
89
90
|
const sortBy = params.sortBy ? params.sortBy : 'lastCreated';
|
|
90
91
|
posts = posts.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
|
|
91
92
|
|
|
92
|
-
if (params.includeDeleted
|
|
93
|
+
if (!params.includeDeleted) {
|
|
93
94
|
posts = filterByPropEquality(posts, 'isDeleted', false);
|
|
94
95
|
}
|
|
95
96
|
|
|
@@ -101,6 +102,10 @@ export const livePosts = (
|
|
|
101
102
|
posts = filterByFeedType(posts, params.feedType);
|
|
102
103
|
}
|
|
103
104
|
|
|
105
|
+
if (params.dataTypes?.length) {
|
|
106
|
+
posts = filterByPostDataTypes(posts, params.dataTypes);
|
|
107
|
+
}
|
|
108
|
+
|
|
104
109
|
callback({
|
|
105
110
|
onNextPage: onFetch,
|
|
106
111
|
data: posts,
|
|
@@ -127,20 +132,21 @@ export const livePosts = (
|
|
|
127
132
|
}
|
|
128
133
|
|
|
129
134
|
pushToCache(cacheKey, collection);
|
|
135
|
+
disposers.push(() => dropFromCache(cacheKey));
|
|
130
136
|
|
|
131
137
|
responder(collection);
|
|
132
138
|
};
|
|
133
139
|
|
|
134
|
-
const onFetch = () => {
|
|
140
|
+
const onFetch = (initial = false) => {
|
|
135
141
|
const collection = pullFromCache<Amity.PostLiveCollectionCache>(cacheKey)?.data;
|
|
136
142
|
|
|
137
143
|
const posts = collection?.data ?? [];
|
|
138
144
|
|
|
139
|
-
if (posts.length > 0 && !collection?.params?.page) return;
|
|
145
|
+
if (!initial && posts.length > 0 && !collection?.params?.page) return;
|
|
140
146
|
|
|
141
147
|
const query = createQuery(queryPosts, {
|
|
142
148
|
...queryParams,
|
|
143
|
-
page: collection?.params
|
|
149
|
+
page: (!initial ? collection?.params.page : undefined) ?? { limit },
|
|
144
150
|
});
|
|
145
151
|
|
|
146
152
|
runQuery(
|
|
@@ -178,11 +184,10 @@ export const livePosts = (
|
|
|
178
184
|
onPostReactionRemoved(realtimeRouter('onReactionRemoved')),
|
|
179
185
|
);
|
|
180
186
|
|
|
181
|
-
onFetch();
|
|
187
|
+
onFetch(true);
|
|
182
188
|
|
|
183
189
|
return () => {
|
|
184
190
|
log(`livePosts(tmpid: ${timestamp}) > dispose`);
|
|
185
191
|
disposers.forEach(fn => fn());
|
|
186
|
-
dropFromCache(cacheKey);
|
|
187
192
|
};
|
|
188
193
|
};
|
|
@@ -66,7 +66,7 @@ describe('livePosts', () => {
|
|
|
66
66
|
|
|
67
67
|
const filters: [string, Amity.PostLiveCollection, number?][] = [
|
|
68
68
|
['not deleted', { ...params, includeDeleted: false }],
|
|
69
|
-
['tags', { ...params, tags: ['test_tag'] }, 1],
|
|
69
|
+
['tags', { ...params, tags: ['test_tag'], includeDeleted: true }, 1],
|
|
70
70
|
];
|
|
71
71
|
|
|
72
72
|
test.each(filters)(
|
|
@@ -104,7 +104,7 @@ describe('livePosts', () => {
|
|
|
104
104
|
.mockResolvedValue(postQueryResponse)
|
|
105
105
|
.mockResolvedValueOnce(postQueryResponsePage2);
|
|
106
106
|
|
|
107
|
-
livePosts(params, callback);
|
|
107
|
+
livePosts({ ...params, includeDeleted: true }, callback);
|
|
108
108
|
|
|
109
109
|
expect(callback).toHaveBeenCalled();
|
|
110
110
|
|
|
@@ -292,7 +292,10 @@ describe('livePosts', () => {
|
|
|
292
292
|
const callback = jest.fn();
|
|
293
293
|
client.http.get = jest.fn().mockResolvedValue(postQueryResponsePage2);
|
|
294
294
|
|
|
295
|
-
livePosts(
|
|
295
|
+
livePosts(
|
|
296
|
+
{ ...params, targetType: 'community', feedType: 'reviewing', includeDeleted: true },
|
|
297
|
+
callback,
|
|
298
|
+
);
|
|
296
299
|
|
|
297
300
|
await pause();
|
|
298
301
|
const payload = postQueryResponsePage2.data.posts;
|
|
@@ -335,7 +338,10 @@ describe('livePosts', () => {
|
|
|
335
338
|
const callback = jest.fn();
|
|
336
339
|
client.http.get = jest.fn().mockResolvedValue(postQueryResponsePage2);
|
|
337
340
|
|
|
338
|
-
livePosts(
|
|
341
|
+
livePosts(
|
|
342
|
+
{ ...params, targetType: 'community', feedType: 'published', includeDeleted: true },
|
|
343
|
+
callback,
|
|
344
|
+
);
|
|
339
345
|
|
|
340
346
|
await pause();
|
|
341
347
|
const payload = postQueryResponsePage2.data.posts;
|
|
@@ -88,16 +88,16 @@ export const liveReactions = (
|
|
|
88
88
|
responder(collection);
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
-
const onFetch = () => {
|
|
91
|
+
const onFetch = (initial = false) => {
|
|
92
92
|
const collection = pullFromCache<Amity.ReactionLiveCollectionCache>(cacheKey)?.data;
|
|
93
93
|
|
|
94
94
|
const reactions = collection?.data ?? [];
|
|
95
95
|
|
|
96
|
-
if (reactions.length > 0 && !collection?.params?.page) return;
|
|
96
|
+
if (!initial && reactions.length > 0 && !collection?.params?.page) return;
|
|
97
97
|
|
|
98
98
|
const query = createQuery(queryReactions, {
|
|
99
99
|
...queryParams,
|
|
100
|
-
page: collection?.params
|
|
100
|
+
page: (!initial ? collection?.params.page : undefined) ?? { limit },
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
runQuery(
|
|
@@ -133,7 +133,7 @@ export const liveReactions = (
|
|
|
133
133
|
),
|
|
134
134
|
);
|
|
135
135
|
|
|
136
|
-
onFetch();
|
|
136
|
+
onFetch(true);
|
|
137
137
|
|
|
138
138
|
return () => {
|
|
139
139
|
log(`liveReactions(tmpid: ${timestamp}) > dispose`);
|
|
@@ -4,6 +4,8 @@ import { getActiveClient } from '~/client/api';
|
|
|
4
4
|
import { getResolver } from '~/core/model';
|
|
5
5
|
import { toPage, toToken } from '~/core/query';
|
|
6
6
|
import { fireEvent } from '~/core/events';
|
|
7
|
+
|
|
8
|
+
import { inferIsDeleted } from '~/utils/inferIsDeleted';
|
|
7
9
|
import { convertQueryParams, prepareSubChannelPayload } from '../utils';
|
|
8
10
|
|
|
9
11
|
/* begin_public_function
|
|
@@ -36,7 +38,7 @@ export const querySubChannels = async (
|
|
|
36
38
|
{
|
|
37
39
|
params: {
|
|
38
40
|
...params,
|
|
39
|
-
isDeleted: includeDeleted
|
|
41
|
+
isDeleted: inferIsDeleted(includeDeleted),
|
|
40
42
|
options: {
|
|
41
43
|
token: toToken(page, 'skiplimit'),
|
|
42
44
|
},
|
|
@@ -59,7 +59,7 @@ export const liveSubChannels = (
|
|
|
59
59
|
const responder = (data: Amity.SubChannelLiveCollectionCache) => {
|
|
60
60
|
let subChannels: Amity.SubChannel[] = data.data;
|
|
61
61
|
|
|
62
|
-
if (params.includeDeleted
|
|
62
|
+
if (!params.includeDeleted) {
|
|
63
63
|
subChannels = filterByPropEquality(subChannels, 'isDeleted', false);
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -111,16 +111,16 @@ export const liveUsers = (
|
|
|
111
111
|
responder(collection);
|
|
112
112
|
};
|
|
113
113
|
|
|
114
|
-
const onFetch = () => {
|
|
114
|
+
const onFetch = (initial = false) => {
|
|
115
115
|
const collection = pullFromCache<Amity.UserLiveCollectionCache>(cacheKey)?.data;
|
|
116
116
|
|
|
117
117
|
const users = collection?.data ?? [];
|
|
118
118
|
|
|
119
|
-
if (users.length > 0 && !collection?.params.page) return;
|
|
119
|
+
if (!initial && users.length > 0 && !collection?.params.page) return;
|
|
120
120
|
|
|
121
121
|
const query = createQuery(queryUsers, {
|
|
122
122
|
...queryParams,
|
|
123
|
-
page: collection?.params.page ?? { limit },
|
|
123
|
+
page: (!initial ? collection?.params.page : undefined) ?? { limit },
|
|
124
124
|
});
|
|
125
125
|
|
|
126
126
|
runQuery(
|
|
@@ -153,7 +153,7 @@ export const liveUsers = (
|
|
|
153
153
|
onUserFlagCleared(realtimeRouter('onFlagCleared')),
|
|
154
154
|
);
|
|
155
155
|
|
|
156
|
-
onFetch();
|
|
156
|
+
onFetch(true);
|
|
157
157
|
|
|
158
158
|
return () => {
|
|
159
159
|
log(`liveUsers(tmpid: ${timestamp}) > dispose`);
|
|
@@ -65,17 +65,11 @@ describe('liveUsers', () => {
|
|
|
65
65
|
liveUsers(params, callback);
|
|
66
66
|
await pause();
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
// The second `getUsers` call fetches data from the cache,
|
|
69
|
+
// so there is no loading state and the callback only fires once.
|
|
70
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
69
71
|
expect(callback).toHaveBeenNthCalledWith(
|
|
70
72
|
1,
|
|
71
|
-
expect.objectContaining(
|
|
72
|
-
getSnapshot({
|
|
73
|
-
data: payload.users,
|
|
74
|
-
}),
|
|
75
|
-
),
|
|
76
|
-
);
|
|
77
|
-
expect(callback).toHaveBeenNthCalledWith(
|
|
78
|
-
2,
|
|
79
73
|
expect.objectContaining(
|
|
80
74
|
getSnapshot({
|
|
81
75
|
data: payload.users,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a simple utility that infers the value of isDeleted based on the
|
|
3
|
+
* value of includeDeleted
|
|
4
|
+
*
|
|
5
|
+
* There are two important things to note here:
|
|
6
|
+
* 1. `includeDeleted` is purely client side query param and not recognized by
|
|
7
|
+
* the server
|
|
8
|
+
* 2. The only values we wish to expose with regards to `isDeleted` (the server
|
|
9
|
+
* param for queries) is false | undefined and want to disallow users to query
|
|
10
|
+
* for deleted entities
|
|
11
|
+
*
|
|
12
|
+
* Although this is a very simple utility, it's only purpose is to keep things
|
|
13
|
+
* DRY
|
|
14
|
+
*/
|
|
15
|
+
export const inferIsDeleted = (includeDeleted?: boolean): boolean | undefined =>
|
|
16
|
+
includeDeleted === true ? undefined : false;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { inferIsDeleted } from '../inferIsDeleted';
|
|
2
|
+
|
|
3
|
+
describe('utils > inferIsDeleted', () => {
|
|
4
|
+
test('it should return false if includeDeleted false', () => {
|
|
5
|
+
expect(inferIsDeleted(false)).toBe(false);
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
test('it should return false if includeDeleted undefined', () => {
|
|
9
|
+
expect(inferIsDeleted(undefined)).toBe(false);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('it should return undefined if includeDeleted true', () => {
|
|
13
|
+
expect(inferIsDeleted(true)).toBeUndefined();
|
|
14
|
+
});
|
|
15
|
+
});
|