[Manager] Add Algolia search (#3036)

This commit is contained in:
Christian Byrne
2025-03-13 18:24:38 -07:00
committed by GitHub
parent 20d2eca51e
commit 05dd587928
10 changed files with 449 additions and 116 deletions

View File

@@ -1,72 +1,77 @@
import { debounce } from 'lodash'
import { onUnmounted, ref, watch } from 'vue'
import { watchDebounced } from '@vueuse/core'
import { memoize } from 'lodash'
import { computed, ref, watch } from 'vue'
import { useComfyRegistryService } from '@/services/comfyRegistryService'
import { useComfyRegistryStore } from '@/stores/comfyRegistryStore'
import type { components } from '@/types/comfyRegistryTypes'
import {
AlgoliaNodePack,
SearchAttribute,
useAlgoliaSearchService
} from '@/services/algoliaSearchService'
import { PackField } from '@/types/comfyManagerTypes'
const SEARCH_DEBOUNCE_TIME = 256
const DEFAULT_PAGE_SIZE = 60
const DEFAULT_SORT_FIELD: keyof components['schemas']['Node'] = 'downloads'
const SEARCH_DEBOUNCE_TIME = 16
const DEFAULT_PAGE_SIZE = 64
/**
* Composable for managing UI state of Comfy Node Registry search.
*/
export function useRegistrySearch() {
const registryStore = useComfyRegistryStore()
const registryService = useComfyRegistryService()
const searchQuery = ref('')
const pageNumber = ref(1)
const isLoading = ref(false)
const sortField = ref<PackField>('downloads')
const searchMode = ref<'nodes' | 'packs'>('packs')
const pageSize = ref(DEFAULT_PAGE_SIZE)
const sortField = ref<keyof components['schemas']['Node']>(DEFAULT_SORT_FIELD)
const searchResults = ref<components['schemas']['Node'][]>([])
const pageNumber = ref(0)
const searchQuery = ref('')
const results = ref<AlgoliaNodePack[]>([])
const search = async () => {
try {
const isEmptySearch = searchQuery.value === ''
const result = isEmptySearch
? await registryStore.listAllPacks({
page: pageNumber.value,
limit: pageSize.value,
sort: [sortField.value]
})
: await registryService.search({
search: searchQuery.value,
page: pageNumber.value,
limit: pageSize.value
})
const searchAttributes = computed<SearchAttribute[]>(() =>
searchMode.value === 'nodes' ? ['comfy_nodes'] : ['name', 'description']
)
if (result) {
searchResults.value = result.nodes || []
} else {
searchResults.value = []
}
} catch (err) {
console.error('Error loading packs:', err)
searchResults.value = []
}
const resultsAsRegistryPacks = computed(() =>
results.value ? results.value.map(algoliaToRegistry) : []
)
const resultsAsNodes = computed(() =>
results.value
? results.value.reduce(
(acc, hit) => acc.concat(hit.comfy_nodes),
[] as string[]
)
: []
)
const { searchPacks, toRegistryPack } = useAlgoliaSearchService()
const algoliaToRegistry = memoize(
toRegistryPack,
(algoliaNode: AlgoliaNodePack) => algoliaNode.id
)
const onQueryChange = async () => {
isLoading.value = true
results.value = await searchPacks(searchQuery.value, {
pageSize: pageSize.value,
pageNumber: pageNumber.value,
restrictSearchableAttributes: searchAttributes.value
})
isLoading.value = false
}
const debouncedSearch = debounce(search, SEARCH_DEBOUNCE_TIME)
// Debounce search when query changes
watch(() => searchQuery.value, debouncedSearch)
watch(() => [pageNumber.value, sortField.value], search, { immediate: true })
onUnmounted(() => {
debouncedSearch.cancel() // Cancel debounced searches
registryStore.cancelRequests() // Cancel in-flight requests
watch([pageNumber, sortField, searchMode], onQueryChange, {
immediate: true
})
watchDebounced(searchQuery, onQueryChange, {
debounce: SEARCH_DEBOUNCE_TIME
})
return {
isLoading,
pageNumber,
pageSize,
sortField,
searchMode,
searchQuery,
searchResults,
isLoading: registryService.isLoading,
error: registryService.error
searchResults: resultsAsRegistryPacks,
nodeSearchResults: resultsAsNodes
}
}