import { fetchMeilisearchResults } from '../search/index.js' import type { AlgoliaMultipleQueriesQuery, AlgoliaSearchResponse, AlgoliaSearchForFacetValuesResponse, } from '@meilisearch/instant-meilisearch' import type { SearchClient as MeilisearchClient } from '../types/SearchClient.js' // All types copied from: autocomplete/packages/autocomplete-preset-algolia/src/requester/createRequester.ts // As most of the types are not exported and we need to be able to provide our own Fetcher type Fetcher = typeof fetchMeilisearchResults export type FetcherParams = Pick< Parameters[0], 'searchClient' | 'queries' > type FacetHit = { label: string count: number _highlightResult: { label: { value: string } } } type TransformResponseParams = { results: Array< AlgoliaSearchResponse | AlgoliaSearchForFacetValuesResponse > hits: Array['hits']> facetHits: FacetHit[][] } export type TransformedRequesterResponse = | Array['hits']> | AlgoliaSearchResponse['hits'] | FacetHit[][] | FacetHit[] export type TransformResponse = ( response: TransformResponseParams ) => TransformedRequesterResponse export type RequesterParams = { transformResponse( response: TransformResponseParams ): TransformedRequesterResponse } type FetcherParamsQuery = { query: AlgoliaMultipleQueriesQuery sourceId: string transformResponse: TransformResponse } type ExecuteParams = { searchClient: MeilisearchClient requests: Array> } export type ExecuteResponse = Array<{ items: AlgoliaSearchResponse | AlgoliaSearchForFacetValuesResponse sourceId: string transformResponse: TransformResponse }> export type Execute = ( params: ExecuteParams ) => Promise> export type RequestParams = FetcherParams & { /** * The function to transform the Algolia response before passing it to the * Autocomplete state. You have access to the full Algolia results, as well as * the pre-computed hits and facet hits. * * This is useful to manipulate the hits, or store data from the results in * the * [context](https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/context/). */ transformResponse?: TransformResponse } export type RequesterDescription = { /** * The search client used for this request. Multiple queries with the same * client are batched (if `requesterId` is also the same). */ searchClient: any /** * Identifies requesters to confirm their queries should be batched. This * ensures that requesters with the same client but different post-processing * functions don't get batched. When falsy, batching is disabled. For example, * the Algolia requesters use "algolia". */ requesterId?: string /** The search parameters used for this query. */ queries: AlgoliaMultipleQueriesQuery[] /** Transforms the response of this search before returning it to the caller. */ transformResponse: TransformResponse /** Post-processing function for multi-queries. */ execute: Execute } export function createRequester(fetcher: Fetcher, requesterId?: string) { function execute(fetcherParams: ExecuteParams) { return fetcher({ searchClient: fetcherParams.searchClient, queries: fetcherParams.requests.map((x) => x.query), }).then((responses) => responses.map((response, index) => { const { sourceId, transformResponse } = fetcherParams.requests[index] return { items: response, sourceId, transformResponse, } }) ) } return function createSpecifiedRequester( requesterParams: RequesterParams ) { return function requester( requestParams: RequestParams ): RequesterDescription { return { requesterId, execute, ...requesterParams, ...requestParams, } } } }