diff --git a/package.json b/package.json index 8015f87..1febc03 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@afosto/instant-search-client", - "version": "1.0.2", + "version": "1.0.3", "private": false, "description": "The Afosto InstantSearch client", "main": "./dist/afosto-instant-search.min.js", @@ -53,6 +53,9 @@ "webpack-cli": "^4.9.1", "webpack-dev-server": "^4.6.0" }, + "dependencies": { + "uuid": "^8.3.2" + }, "browserslist": [ ">0.2%", "not dead", diff --git a/playground/index.html b/playground/index.html index 3d6e722..710bd0d 100644 --- a/playground/index.html +++ b/playground/index.html @@ -66,10 +66,6 @@

Products

}); search.addWidgets([ - instantsearch.widgets.configure({ - facets: ['main_genre', 'release_year_range'], - }), - instantsearch.widgets.searchBox({ container: '#searchbox', }), @@ -84,9 +80,8 @@

Products

instantsearch.widgets.dynamicWidgets({ container: '#dynamic-list', - facets: [], transformItems(_, { results }) { - return results.facets.map(facet => facet.name); + return Object.keys(results._rawResults[0].facets); }, widgets: filterKeys.map((attribute) => (container) => instantsearch.widgets.panel({ diff --git a/src/adapters/SearchRequestAdapter.js b/src/adapters/SearchRequestAdapter.js index f50c280..8da8670 100644 --- a/src/adapters/SearchRequestAdapter.js +++ b/src/adapters/SearchRequestAdapter.js @@ -119,6 +119,7 @@ const SearchRequestAdapter = () => { indices: [request.indexName], q: query, threshold: options.threshold || DEFAULT_OPTIONS.threshold, + __queryID: request.__queryID, ...pagination, }]; }, []); diff --git a/src/adapters/SearchResponseAdapter.js b/src/adapters/SearchResponseAdapter.js index 2e2422f..9de8823 100644 --- a/src/adapters/SearchResponseAdapter.js +++ b/src/adapters/SearchResponseAdapter.js @@ -22,6 +22,7 @@ const SearchResponseAdapter = () => { const nbHits = results.count ?? 0; const nbPages = Math.ceil(nbHits / hitsPerPage); const index = results.id ?? request?.indexName; + const queryID = results.__queryID ?? index; return { facets, @@ -33,7 +34,7 @@ const SearchResponseAdapter = () => { nbPages, page, query, - queryID: index, + queryID, }; }; diff --git a/src/afostoInstantSearch.js b/src/afostoInstantSearch.js index d56a28e..0a42bf5 100644 --- a/src/afostoInstantSearch.js +++ b/src/afostoInstantSearch.js @@ -1,3 +1,4 @@ +import { v4 as uuid } from 'uuid'; import { SearchResponseAdapter, SearchRequestAdapter } from './adapters'; import { DEFAULT_OPTIONS } from './constants'; @@ -33,11 +34,11 @@ const afostoInstantSearch = (searchEngineKey, options = {}) => { } }; - const searchRequest = async context => { + const searchRequest = async contexts => { const requestOptions = clientOptions.requestOptions || {}; const hasContextFormatter = clientOptions.transformContext && typeof clientOptions.transformContext === 'function'; const hasResponseFormatter = clientOptions.transformResponse && typeof clientOptions.transformResponse === 'function'; - const payload = hasContextFormatter ? clientOptions.transformContext(context) : context; + const payload = hasContextFormatter ? contexts.map(context => clientOptions.transformContext(context)) : contexts; const searchResponse = await fetch(url, { ...requestOptions, method: 'POST', @@ -47,27 +48,27 @@ const afostoInstantSearch = (searchEngineKey, options = {}) => { }, body: JSON.stringify({ data: payload }), }); - const response = await searchResponse.json(); + const responses = await searchResponse.json(); + const formattedResponses = Array.isArray(responses) ? responses: [responses]; - return hasResponseFormatter ? clientOptions.transformResponse(response) : response; + return hasResponseFormatter ? formattedResponses.map(response => clientOptions.transformResponse(response)) : formattedResponses; } const search = async requests => { try { - const searchContexts = searchRequestAdapter.transform(requests, clientOptions); + const searchRequests = requests.map(request => ({ ...request, __queryID: uuid() })); + const searchContexts = searchRequestAdapter.transform(searchRequests, clientOptions); const [searchRequestContext] = searchContexts; if (!clientOptions.allowEmptyQuery && !searchRequestContext?.q) { - return searchResponseAdapter.transform({}, requests, clientOptions); + return searchResponseAdapter.transform({}, searchRequests, clientOptions); } - const promises = searchContexts.map(context => searchRequest(context)); - const responses = await Promise.allSettled(promises); - const responseValues = responses.map(response => response.value || {}); - - const results = requests.reduce((acc, request, idx) => { - const response = searchResponseAdapter.transform(responseValues[idx], request, clientOptions); - return [...acc, response]; + const responses = await searchRequest(searchContexts); + const results = searchRequests.reduce((acc, request) => { + const response = responses.find(value => value.__queryID === request.__queryID); + const result = searchResponseAdapter.transform(response, request, clientOptions); + return [...acc, result]; }, []); return { results }; diff --git a/src/constants.js b/src/constants.js index 8987c90..6e32495 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,6 +1,6 @@ export const DEFAULT_OPTIONS = { allowEmptyQuery: true, - baseUrl: 'https://afosto.io/api/instant/search/{key}', + baseUrl: 'https://afosto.app/api/instant/search/{key}', hitsPerPage: 10, requestOptions: {}, settingsRequestOptions: {},