diff --git a/src/components/dialog/content/manager/packCard/PackCard.vue b/src/components/dialog/content/manager/packCard/PackCard.vue index 45afb2c3b9..7767e900d2 100644 --- a/src/components/dialog/content/manager/packCard/PackCard.vue +++ b/src/components/dialog/content/manager/packCard/PackCard.vue @@ -113,11 +113,15 @@ import PackBanner from '@/components/dialog/content/manager/packBanner/PackBanne import PackCardFooter from '@/components/dialog/content/manager/packCard/PackCardFooter.vue' import { usePackUpdateStatus } from '@/composables/nodePack/usePackUpdateStatus' import { useComfyManagerStore } from '@/stores/comfyManagerStore' -import { IsInstallingKey } from '@/types/comfyManagerTypes' -import type { components } from '@/types/comfyRegistryTypes' +import { + IsInstallingKey, + type MergedNodePack, + type RegistryPack, + isMergedNodePack +} from '@/types/comfyManagerTypes' const { nodePack, isSelected = false } = defineProps<{ - nodePack: components['schemas']['Node'] + nodePack: MergedNodePack | RegistryPack isSelected?: boolean }>() @@ -136,9 +140,9 @@ const isDisabled = computed( whenever(isInstalled, () => (isInstalling.value = false)) -// TODO: remove type assertion once comfy_nodes is added to node (pack) info type in backend -const nodesCount = computed(() => (nodePack as any).comfy_nodes?.length) - +const nodesCount = computed(() => + isMergedNodePack(nodePack) ? nodePack.comfy_nodes?.length : undefined +) const publisherName = computed(() => { if (!nodePack) return null diff --git a/src/components/dialog/content/manager/registrySearchBar/RegistrySearchBar.vue b/src/components/dialog/content/manager/registrySearchBar/RegistrySearchBar.vue index 37a7481610..9c27404825 100644 --- a/src/components/dialog/content/manager/registrySearchBar/RegistrySearchBar.vue +++ b/src/components/dialog/content/manager/registrySearchBar/RegistrySearchBar.vue @@ -56,7 +56,7 @@ import { computed } from 'vue' import { useI18n } from 'vue-i18n' import SearchFilterDropdown from '@/components/dialog/content/manager/registrySearchBar/SearchFilterDropdown.vue' -import type { NodesIndexSuggestion } from '@/services/algoliaSearchService' +import type { NodesIndexSuggestion } from '@/types/algoliaTypes' import { type SearchOption, SortableAlgoliaField diff --git a/src/composables/useRegistrySearch.ts b/src/composables/useRegistrySearch.ts index 8c0c5ffd0b..ab30121b37 100644 --- a/src/composables/useRegistrySearch.ts +++ b/src/composables/useRegistrySearch.ts @@ -3,12 +3,12 @@ import type { Hit } from 'algoliasearch/dist/lite/browser' import { memoize, orderBy } from 'lodash' import { computed, onUnmounted, ref, watch } from 'vue' -import { +import { useAlgoliaSearchService } from '@/services/algoliaSearchService' +import type { AlgoliaNodePack, - SearchAttribute, - useAlgoliaSearchService -} from '@/services/algoliaSearchService' -import type { NodesIndexSuggestion } from '@/services/algoliaSearchService' + NodesIndexSuggestion, + SearchAttribute +} from '@/types/algoliaTypes' import { SortableAlgoliaField } from '@/types/comfyManagerTypes' const SEARCH_DEBOUNCE_TIME = 320 diff --git a/src/services/algoliaSearchService.ts b/src/services/algoliaSearchService.ts index 5b306987ad..f1e7825a95 100644 --- a/src/services/algoliaSearchService.ts +++ b/src/services/algoliaSearchService.ts @@ -1,68 +1,26 @@ import QuickLRU from '@alloc/quick-lru' import type { - BaseSearchParamsWithoutQuery, - Hit, SearchQuery, SearchResponse } from 'algoliasearch/dist/lite/browser' import { liteClient as algoliasearch } from 'algoliasearch/dist/lite/builds/browser' import { omit } from 'lodash' -import { components } from '@/types/comfyRegistryTypes' +import type { + AlgoliaNodePack, + NodesIndexSuggestion, + SearchAttribute, + SearchNodePacksParams, + SearchPacksResult +} from '@/types/algoliaTypes' +import type { components } from '@/types/comfyRegistryTypes' import { paramsToCacheKey } from '@/utils/formatUtil' +type RegistryNodePack = components['schemas']['Node'] + const DEFAULT_MAX_CACHE_SIZE = 64 const DEFAULT_MIN_CHARS_FOR_SUGGESTIONS = 2 -type SafeNestedProperty< - T, - K1 extends keyof T, - K2 extends keyof NonNullable -> = T[K1] extends undefined | null ? undefined : NonNullable[K2] - -type RegistryNodePack = components['schemas']['Node'] -type SearchPacksResult = { - nodePacks: Hit[] - querySuggestions: Hit[] -} - -export interface AlgoliaNodePack { - objectID: RegistryNodePack['id'] - name: RegistryNodePack['name'] - publisher_id: SafeNestedProperty - description: RegistryNodePack['description'] - comfy_nodes: string[] - total_install: RegistryNodePack['downloads'] - id: RegistryNodePack['id'] - create_time: string - update_time: SafeNestedProperty< - RegistryNodePack, - 'latest_version', - 'createdAt' - > - license: RegistryNodePack['license'] - repository_url: RegistryNodePack['repository'] - status: RegistryNodePack['status'] - latest_version: SafeNestedProperty< - RegistryNodePack, - 'latest_version', - 'version' - > - latest_version_status: SafeNestedProperty< - RegistryNodePack, - 'latest_version', - 'status' - > - comfy_node_extract_status: SafeNestedProperty< - RegistryNodePack, - 'latest_version', - 'comfy_node_extract_status' - > - icon_url: RegistryNodePack['icon'] -} - -export type SearchAttribute = keyof AlgoliaNodePack - const RETRIEVE_ATTRIBUTES: SearchAttribute[] = [ 'comfy_nodes', 'name', @@ -81,26 +39,6 @@ const RETRIEVE_ATTRIBUTES: SearchAttribute[] = [ 'icon_url' ] -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 - restrictSearchableAttributes: SearchAttribute[] -} - interface AlgoliaSearchServiceOptions { /** * Maximum number of search results to store in the cache. diff --git a/src/types/algoliaTypes.ts b/src/types/algoliaTypes.ts new file mode 100644 index 0000000000..4e00812c87 --- /dev/null +++ b/src/types/algoliaTypes.ts @@ -0,0 +1,74 @@ +import type { + BaseSearchParamsWithoutQuery, + Hit +} from 'algoliasearch/dist/lite/browser' + +import type { components } from '@/types/comfyRegistryTypes' + +type SafeNestedProperty< + T, + K1 extends keyof T, + K2 extends keyof NonNullable +> = T[K1] extends undefined | null ? undefined : NonNullable[K2] + +type RegistryNodePack = components['schemas']['Node'] +export type SearchPacksResult = { + nodePacks: Hit[] + querySuggestions: Hit[] +} + +export interface AlgoliaNodePack { + objectID: RegistryNodePack['id'] + name: RegistryNodePack['name'] + publisher_id: SafeNestedProperty + description: RegistryNodePack['description'] + comfy_nodes: string[] + total_install: RegistryNodePack['downloads'] + id: RegistryNodePack['id'] + create_time: string + update_time: SafeNestedProperty< + RegistryNodePack, + 'latest_version', + 'createdAt' + > + license: RegistryNodePack['license'] + repository_url: RegistryNodePack['repository'] + status: RegistryNodePack['status'] + latest_version: SafeNestedProperty< + RegistryNodePack, + 'latest_version', + 'version' + > + latest_version_status: SafeNestedProperty< + RegistryNodePack, + 'latest_version', + 'status' + > + comfy_node_extract_status: SafeNestedProperty< + RegistryNodePack, + 'latest_version', + 'comfy_node_extract_status' + > + icon_url: RegistryNodePack['icon'] +} + +export type SearchAttribute = keyof AlgoliaNodePack +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 +} + +export type SearchNodePacksParams = BaseSearchParamsWithoutQuery & { + pageSize: number + pageNumber: number + restrictSearchableAttributes: SearchAttribute[] +} diff --git a/src/types/comfyManagerTypes.ts b/src/types/comfyManagerTypes.ts index 6ae2023560..dbb8bc1696 100644 --- a/src/types/comfyManagerTypes.ts +++ b/src/types/comfyManagerTypes.ts @@ -1,10 +1,17 @@ import type { InjectionKey, Ref } from 'vue' import type { ComfyWorkflowJSON } from '@/schemas/comfyWorkflowSchema' +import type { AlgoliaNodePack } from '@/types/algoliaTypes' import type { components } from '@/types/comfyRegistryTypes' -type RegistryPack = components['schemas']['Node'] type WorkflowNodeProperties = ComfyWorkflowJSON['nodes'][0]['properties'] + +export type RegistryPack = components['schemas']['Node'] +export type MergedNodePack = RegistryPack & AlgoliaNodePack +export const isMergedNodePack = ( + nodePack: RegistryPack | AlgoliaNodePack +): nodePack is MergedNodePack => 'comfy_nodes' in nodePack + export type PackField = keyof RegistryPack | null export const IsInstallingKey: InjectionKey> =