diff --git a/src/components/dialog/content/manager/ManagerDialogContent.vue b/src/components/dialog/content/manager/ManagerDialogContent.vue index 21b0e68d7..05fa6830c 100644 --- a/src/components/dialog/content/manager/ManagerDialogContent.vue +++ b/src/components/dialog/content/manager/ManagerDialogContent.vue @@ -32,6 +32,7 @@ v-model:searchQuery="searchQuery" v-model:searchMode="searchMode" :searchResults="searchResults" + :suggestions="suggestions" />
([ ]) const selectedTab = ref(tabs.value[0]) -const { searchQuery, pageNumber, isLoading, searchResults, searchMode } = - useRegistrySearch() +const { + searchQuery, + pageNumber, + isLoading, + searchResults, + searchMode, + suggestions +} = useRegistrySearch() pageNumber.value = 0 const isInitialLoad = computed( diff --git a/src/components/dialog/content/manager/registrySearchBar/RegistrySearchBar.vue b/src/components/dialog/content/manager/registrySearchBar/RegistrySearchBar.vue index 027d334ce..99bd6f3c4 100644 --- a/src/components/dialog/content/manager/registrySearchBar/RegistrySearchBar.vue +++ b/src/components/dialog/content/manager/registrySearchBar/RegistrySearchBar.vue @@ -1,15 +1,29 @@ diff --git a/src/composables/useRegistrySearch.ts b/src/composables/useRegistrySearch.ts index 7c5750654..0ee30cc22 100644 --- a/src/composables/useRegistrySearch.ts +++ b/src/composables/useRegistrySearch.ts @@ -7,6 +7,7 @@ import { SearchAttribute, useAlgoliaSearchService } from '@/services/algoliaSearchService' +import type { NodesIndexSuggestion } from '@/services/algoliaSearchService' import { PackField } from '@/types/comfyManagerTypes' const SEARCH_DEBOUNCE_TIME = 16 @@ -23,6 +24,7 @@ export function useRegistrySearch() { const pageNumber = ref(0) const searchQuery = ref('') const results = ref([]) + const suggestions = ref([]) const searchAttributes = computed(() => searchMode.value === 'nodes' ? ['comfy_nodes'] : ['name', 'description'] @@ -49,11 +51,16 @@ export function useRegistrySearch() { const onQueryChange = async () => { isLoading.value = true - results.value = await searchPacks(searchQuery.value, { - pageSize: pageSize.value, - pageNumber: pageNumber.value, - restrictSearchableAttributes: searchAttributes.value - }) + const { nodePacks, querySuggestions } = await searchPacks( + searchQuery.value, + { + pageSize: pageSize.value, + pageNumber: pageNumber.value, + restrictSearchableAttributes: searchAttributes.value + } + ) + results.value = nodePacks + suggestions.value = querySuggestions isLoading.value = false } @@ -71,6 +78,7 @@ export function useRegistrySearch() { sortField, searchMode, searchQuery, + suggestions, searchResults: resultsAsRegistryPacks, nodeSearchResults: resultsAsNodes } diff --git a/src/services/algoliaSearchService.ts b/src/services/algoliaSearchService.ts index e3268205d..72bf8e81f 100644 --- a/src/services/algoliaSearchService.ts +++ b/src/services/algoliaSearchService.ts @@ -1,6 +1,7 @@ import type { BaseSearchParamsWithoutQuery, - Hit + Hit, + SearchResponse } from 'algoliasearch/dist/lite/browser' import { liteClient as algoliasearch } from 'algoliasearch/dist/lite/builds/browser' import { omit } from 'lodash' @@ -50,6 +51,8 @@ export interface AlgoliaNodePack { 'latest_version', 'comfy_node_extract_status' > + /** `total_install` index only */ + icon_url: RegistryNodePack['icon'] } export type SearchAttribute = keyof AlgoliaNodePack @@ -70,6 +73,20 @@ const RETRIEVE_ATTRIBUTES: SearchAttribute[] = [ 'id' ] +export interface NodesIndexSuggestion { + nb_words: number + nodes_index: { + exact_nb_hits: number + facets: { + exact_matches: Record + analytics: Record + } + } + objectID: RegistryNodePack['id'] + popularity: number + query: string +} + type SearchNodePacksParams = BaseSearchParamsWithoutQuery & { pageSize: number pageNumber: number @@ -112,6 +129,7 @@ export const useAlgoliaSearchService = () => { license: algoliaNode.license, downloads: algoliaNode.total_install, status: algoliaNode.status, + icon: algoliaNode.icon_url, latest_version: toRegistryLatestVersion(algoliaNode), publisher: toRegistryPublisher(algoliaNode) } @@ -123,11 +141,16 @@ export const useAlgoliaSearchService = () => { const searchPacks = async ( query: string, params: SearchNodePacksParams - ): Promise[]> => { + ): Promise<{ + nodePacks: Hit[] + querySuggestions: Hit[] + }> => { const { pageSize, pageNumber } = params const rest = omit(params, ['pageSize', 'pageNumber']) - const { results } = await searchClient.search({ + const { results } = await searchClient.search< + AlgoliaNodePack | NodesIndexSuggestion + >({ requests: [ { query, @@ -135,15 +158,25 @@ export const useAlgoliaSearchService = () => { attributesToRetrieve: RETRIEVE_ATTRIBUTES, ...rest, hitsPerPage: pageSize, - length: pageSize, page: pageNumber + }, + { + indexName: 'nodes_index_query_suggestions', + query } ], strategy: 'none' }) - // Narrow from `SearchResponse | SearchForFacetValuesResponse` to `SearchResponse` - return 'hits' in results[0] ? results[0].hits : [] // Only querying a single index for now + const [nodePacks, querySuggestions] = results as [ + SearchResponse, + SearchResponse + ] + + return { + nodePacks: nodePacks.hits, + querySuggestions: querySuggestions.hits + } } return {