diff --git a/src/services/providers/registrySearchProvider.test.ts b/src/services/providers/registrySearchProvider.test.ts index fe25018ad..b564bf7a7 100644 --- a/src/services/providers/registrySearchProvider.test.ts +++ b/src/services/providers/registrySearchProvider.test.ts @@ -11,6 +11,8 @@ vi.mock('@/stores/comfyRegistryStore', () => ({ describe('useComfyRegistrySearchProvider', () => { const mockSearchCall = vi.fn() const mockSearchClear = vi.fn() + const mockListAllPacksCall = vi.fn() + const mockListAllPacksClear = vi.fn() beforeEach(() => { vi.clearAllMocks() @@ -20,6 +22,10 @@ describe('useComfyRegistrySearchProvider', () => { search: { call: mockSearchCall, clear: mockSearchClear + }, + listAllPacks: { + call: mockListAllPacksCall, + clear: mockListAllPacksClear } } as any) }) @@ -111,14 +117,85 @@ describe('useComfyRegistrySearchProvider', () => { expect(result.nodePacks).toEqual([]) expect(result.querySuggestions).toEqual([]) }) + + it('should use listAllPacks for empty query', async () => { + const mockResults = { + nodes: [ + { id: '1', name: 'Pack 1' }, + { id: '2', name: 'Pack 2' } + ] + } + mockListAllPacksCall.mockResolvedValue(mockResults) + + const provider = useComfyRegistrySearchProvider() + const result = await provider.searchPacks('', { + pageSize: 20, + pageNumber: 0 + }) + + expect(mockListAllPacksCall).toHaveBeenCalledWith({ + limit: 20, + page: 1 + }) + expect(mockSearchCall).not.toHaveBeenCalled() + expect(result.nodePacks).toEqual(mockResults.nodes) + expect(result.querySuggestions).toEqual([]) + }) + + it('should use listAllPacks for whitespace-only query', async () => { + const mockResults = { + nodes: [{ id: '1', name: 'Pack 1' }] + } + mockListAllPacksCall.mockResolvedValue(mockResults) + + const provider = useComfyRegistrySearchProvider() + const result = await provider.searchPacks(' ', { + pageSize: 10, + pageNumber: 0 + }) + + expect(mockListAllPacksCall).toHaveBeenCalledWith({ + limit: 10, + page: 1 + }) + expect(mockSearchCall).not.toHaveBeenCalled() + expect(result.nodePacks).toEqual(mockResults.nodes) + }) + + it('should handle empty results from listAllPacks', async () => { + mockListAllPacksCall.mockResolvedValue({ nodes: [] }) + + const provider = useComfyRegistrySearchProvider() + const result = await provider.searchPacks('', { + pageSize: 10, + pageNumber: 0 + }) + + expect(result.nodePacks).toEqual([]) + expect(result.querySuggestions).toEqual([]) + }) + + it('should handle null results from listAllPacks', async () => { + mockListAllPacksCall.mockResolvedValue(null) + + const provider = useComfyRegistrySearchProvider() + const result = await provider.searchPacks('', { + pageSize: 10, + pageNumber: 0 + }) + + expect(result.nodePacks).toEqual([]) + expect(result.querySuggestions).toEqual([]) + }) }) describe('clearSearchCache', () => { - it('should delegate to store search.clear', () => { + it('should clear both search and listAllPacks caches', () => { const provider = useComfyRegistrySearchProvider() provider.clearSearchCache() expect(mockSearchClear).toHaveBeenCalled() + expect(mockListAllPacksClear).toHaveBeenCalled() }) }) diff --git a/src/services/providers/registrySearchProvider.ts b/src/services/providers/registrySearchProvider.ts index a2cede14a..d9f334205 100644 --- a/src/services/providers/registrySearchProvider.ts +++ b/src/services/providers/registrySearchProvider.ts @@ -25,33 +25,45 @@ export const useComfyRegistrySearchProvider = (): NodePackSearchProvider => { ): Promise => { const { pageSize, pageNumber, restrictSearchableAttributes } = params - // Determine search mode based on searchable attributes + // For empty queries, use the cached listAllPacks endpoint instead of search + if (!query || query.trim() === '') { + const listParams = { + limit: pageSize, + page: pageNumber + 1 // Registry API uses 1-based pagination + // Note: omitting 'latest' parameter defaults to cached result + } + + const listResult = await registryStore.listAllPacks.call(listParams) + const nodePacks = listResult?.nodes ?? [] + + return { + nodePacks, + querySuggestions: [] + } + } + + // For non-empty queries, use the search endpoint const isNodeSearch = restrictSearchableAttributes?.includes('comfy_nodes') const searchParams = { search: isNodeSearch ? undefined : query, comfy_node_search: isNodeSearch ? query : undefined, limit: pageSize, - page: pageNumber + 1 // Registry API uses 1-based pagination + page: pageNumber + 1 } const searchResult = await registryStore.search.call(searchParams) - - if (!searchResult || !searchResult.nodes) { - return { - nodePacks: [], - querySuggestions: [] - } - } + const nodePacks = searchResult?.nodes ?? [] return { - nodePacks: searchResult.nodes, + nodePacks, querySuggestions: [] // Registry doesn't support query suggestions } } const clearSearchCache = () => { registryStore.search.clear() + registryStore.listAllPacks.clear() } const getSortValue = (