diff --git a/app/components/PackageVulnerabilityTree.vue b/app/components/PackageVulnerabilityTree.vue index 7ac9eadf6e..0b5b2a4293 100644 --- a/app/components/PackageVulnerabilityTree.vue +++ b/app/components/PackageVulnerabilityTree.vue @@ -7,17 +7,11 @@ const props = defineProps<{ version: string }>() -const { - data: vulnTree, - status, - fetch: fetchVulnTree, -} = useDependencyAnalysis( +const { data: vulnTree, status } = useDependencyAnalysis( () => props.packageName, () => props.version, ) -onMounted(() => fetchVulnTree()) - const isExpanded = shallowRef(false) const showAllPackages = shallowRef(false) const showAllVulnerabilities = shallowRef(false) diff --git a/app/composables/useDependencyAnalysis.ts b/app/composables/useDependencyAnalysis.ts index 36f1baad1d..d8eee606a2 100644 --- a/app/composables/useDependencyAnalysis.ts +++ b/app/composables/useDependencyAnalysis.ts @@ -1,5 +1,3 @@ -import type { VulnerabilityTreeResult } from '#shared/types/dependency-analysis' - /** * Shared composable for dependency analysis data (vulnerabilities, deprecated packages). * Fetches once and caches the result so multiple components can use it. @@ -9,44 +7,8 @@ export function useDependencyAnalysis( packageName: MaybeRefOrGetter, version: MaybeRefOrGetter, ) { - // Build a stable key from the current values - const name = toValue(packageName) - const ver = toValue(version) - const key = `dep-analysis:v1:${name}@${ver}` - - // Use useState for SSR-safe caching across components - const data = useState(key, () => null) - const status = useState<'idle' | 'pending' | 'success' | 'error'>(`${key}:status`, () => 'idle') - const error = useState(`${key}:error`, () => null) - - async function fetch() { - const pkgName = toValue(packageName) - const pkgVersion = toValue(version) - - if (!pkgName || !pkgVersion) return - - // Already fetched or fetching - if (status.value === 'success' || status.value === 'pending') return - - status.value = 'pending' - error.value = null - - try { - const result = await $fetch( - `/api/registry/vulnerabilities/${encodePackageName(pkgName)}/v/${pkgVersion}`, - ) - data.value = result - status.value = 'success' - } catch (e) { - error.value = e instanceof Error ? e : new Error('Failed to fetch dependency analysis') - status.value = 'error' - } - } - - return { - data: readonly(data), - status: readonly(status), - error: readonly(error), - fetch, - } + return useFetch( + () => + `/api/registry/vulnerabilities/${encodePackageName(toValue(packageName))}/v/${toValue(version)}`, + ) } diff --git a/app/pages/[...package].vue b/app/pages/[...package].vue index d49492afbe..17364baa9e 100644 --- a/app/pages/[...package].vue +++ b/app/pages/[...package].vue @@ -93,24 +93,9 @@ const { copied: copiedPkgName, copy: copyPkgName } = useClipboard({ // Fetch dependency analysis (lazy, client-side) // This is the same composable used by PackageVulnerabilityTree and PackageDeprecatedTree -const { - data: vulnTree, - status: vulnTreeStatus, - fetch: fetchVulnTree, -} = useDependencyAnalysis(packageName, () => displayVersion.value?.version ?? '') -onMounted(() => { - // Fetch vulnerability tree once displayVersion is available - if (displayVersion.value) { - fetchVulnTree() - } -}) -watch( - () => displayVersion.value?.version, - () => { - if (displayVersion.value) { - fetchVulnTree() - } - }, +const { data: vulnTree, status: vulnTreeStatus } = useDependencyAnalysis( + packageName, + () => displayVersion.value?.version ?? '', ) // Keep latestVersion for comparison (to show "(latest)" badge)