import type { Observable } from 'rxjs'; import type { Query } from './query'; import type { Schema } from './schema'; type HighlightAbleField = { [K in keyof S]: S[K] extends 'FullText' ? K : never; }[keyof S]; export interface Searcher { search>( query: Query, options?: O ): Promise>; aggregate>( query: Query, field: keyof S, options?: O ): Promise>; } export interface Subscriber { search$>( query: Query, options?: O ): Observable>; aggregate$>( query: Query, field: keyof S, options?: O ): Observable>; } type ResultPagination = { count: number; limit: number; skip: number; hasMore: boolean; }; type PaginationOption = { limit?: number; skip?: number; }; export type SearchOptions = { pagination?: PaginationOption; highlights?: { field: HighlightAbleField; before: string; end: string; }[]; fields?: (keyof S)[]; }; export type SearchResult> = { pagination: ResultPagination; nodes: ({ id: string; score: number; } & (O['fields'] extends any[] ? { fields: { [key in O['fields'][number]]: string | string[] } } : unknown) & (O['highlights'] extends any[] ? { highlights: { [key in O['highlights'][number]['field']]: string[] } } : unknown))[]; }; export interface AggregateOptions { pagination?: PaginationOption; hits?: SearchOptions; } export type AggregateResult> = { pagination: ResultPagination; buckets: ({ key: string; score: number; count: number; } & (O['hits'] extends object ? { hits: SearchResult } : unknown))[]; };