UNPKG

stream-chat

Version:

JS SDK for the Stream Chat API

97 lines (89 loc) 3.08 kB
import { BaseSearchSource, type SearchQueryOptions } from './BaseSearchSource'; import { FilterBuilder, type FilterBuilderOptions } from '../pagination'; import type { Channel } from '../channel'; import type { ChannelMemberResponse, MemberFilters, MemberSort, QueryMembersOptions, } from '../types'; import type { SearchSourceOptions } from './types'; type CustomContext = Record<string, unknown>; export type ChannelMemberSearchSourceFilterBuilderContext< C extends CustomContext = CustomContext, > = { searchQuery?: string } & C; export type ChannelMemberSearchSourceOptions = SearchSourceOptions & { /** Static base filters merged under the dynamically generated ones. */ filters?: MemberFilters; sort?: MemberSort; searchOptions?: Omit<QueryMembersOptions, 'limit' | 'offset'>; }; export class ChannelMemberSearchSource< TFilterContext extends CustomContext = CustomContext, > extends BaseSearchSource<ChannelMemberResponse> { readonly type = 'members'; channel: Channel; filters: MemberFilters | undefined; sort: MemberSort | undefined; searchOptions: Omit<QueryMembersOptions, 'limit' | 'offset'> | undefined; filterBuilder: FilterBuilder< MemberFilters, ChannelMemberSearchSourceFilterBuilderContext<TFilterContext> >; constructor( channel: Channel, options?: ChannelMemberSearchSourceOptions, filterBuilderOptions: FilterBuilderOptions< MemberFilters, ChannelMemberSearchSourceFilterBuilderContext<TFilterContext> > = {}, ) { const { filters, sort, searchOptions, ...restOptions } = options || {}; // members are listed with an empty query, so the initial load must be allowed super({ ...restOptions, allowEmptySearchString: true }); this.channel = channel; this.filters = filters; this.sort = sort; this.searchOptions = searchOptions; this.filterBuilder = new FilterBuilder< MemberFilters, ChannelMemberSearchSourceFilterBuilderContext<TFilterContext> >({ initialFilterConfig: { default: { enabled: true, generate: ({ searchQuery }) => searchQuery ? { $or: [ { name: { $autocomplete: searchQuery } }, { id: { $eq: searchQuery } }, ], } : null, }, }, ...filterBuilderOptions, }); } protected async query(searchQuery: string, queryOptions: SearchQueryOptions = {}) { const filters = this.filterBuilder.buildFilters({ baseFilters: this.filters, context: { searchQuery, } as ChannelMemberSearchSourceFilterBuilderContext<TFilterContext>, }); const sort = this.sort ?? []; const options = { ...this.searchOptions, limit: this.pageSize, offset: this.offset }; const { members } = await this.channel.queryMembers( filters ?? {}, sort, options, queryOptions, ); return { items: members }; } protected filterQueryResults(items: ChannelMemberResponse[]) { return items; } }