@amityco/ts-sdk-react-native
Version:
Amity Social Cloud Typescript SDK
127 lines (108 loc) • 3.43 kB
text/typescript
import { getActiveClient } from '~/client/api';
import { pullFromCache, pushToCache } from '~/cache/api';
import { ingestInCache } from '~/cache/api/ingestInCache';
import { getResolver } from '~/core/model';
import { fireEvent } from '~/core/events';
import { prepareUserPayload } from '~/userRepository/utils/prepareUserPayload';
/**
* ```js
* import { queryUsers } from '@amityco/ts-sdk-react-native'
* const { data: users, prevPage, nextPage } = await queryUsers({ displayName: 'foo' })
* ```
*
* Queries a paginable list of {@link Amity.InternalUser} objects
* Search is performed by displayName such as `.startsWith(search)`
*
* @param query The query parameters
* @returns A page of {@link Amity.InternalUser} objects
*
* @category User API
* @async
*/
export const queryUsers = async (
query: Amity.QueryUsers = {},
): Promise<Amity.Cached<Amity.PageToken<Amity.InternalUser>>> => {
const client = getActiveClient();
client.log('user/queryUsers', query);
const { page, limit = 10, filter = 'all', sortBy = 'displayName', ...params } = query;
const { data } = await client.http.get<Amity.UserPayload & Amity.Pagination>(`/api/v3/users`, {
params: {
...params,
filter,
sortBy,
options: page ? { token: page } : { limit },
},
});
// unpacking
const { paging, ...rawPayload } = data;
const { users } = rawPayload;
const cachedAt = client.cache && Date.now();
const payload = prepareUserPayload(rawPayload);
if (client.cache) {
ingestInCache(payload, { cachedAt });
/*
* using a query as a cache key over params because if the keyword, filter, sort
* change the API will NOT cache results, when it should
*/
const cacheKey = [
'user',
'query',
{ ...query, options: { limit, token: page } } as Amity.Serializable,
];
pushToCache(cacheKey, { users: users.map(getResolver('user')), paging });
}
fireEvent('user.fetched', data);
return {
data: payload.users,
cachedAt,
paging,
};
};
/**
* ```js
* import { queryUsers } from '@amityco/ts-sdk-react-native'
* const { data: users } = queryUsers.locally({ keyword: 'foo' })
* ```
*
* Queries a paginable list of {@link Amity.InternalUser} objects from cache
* Search is performed by displayName such as `.startsWith(search)`
*
* @param query The query parameters
* @returns A page of {@link Amity.InternalUser} objects
*
* @category User API
*/
queryUsers.locally = (
query: Parameters<typeof queryUsers>[0] = {},
): Amity.Cached<Amity.PageToken<Amity.InternalUser>> | undefined => {
const client = getActiveClient();
client.log('user/queryUsers.locally', query);
if (!client.cache) return;
const { limit = 10, page } = query ?? {};
const cacheKey = [
'user',
'query',
{
...query,
options: {
limit,
token: page,
},
} as Amity.Serializable,
];
const { data, cachedAt } =
pullFromCache<{ users: Pick<Amity.InternalUser, 'userId'>[] } & Amity.Pagination>(cacheKey) ??
{};
const users: Amity.InternalUser[] =
data?.users
.map(userId => pullFromCache<Amity.InternalUser>(['user', 'get', userId])!)
.filter(Boolean)
.map(({ data }) => data) ?? [];
return users.length > 0 && users.length === data?.users?.length
? {
data: users,
cachedAt,
paging: data?.paging,
}
: undefined;
};