MCPcopy Index your code
hub / github.com/npmx-dev/npmx.dev / usePackageComparison

Function usePackageComparison

app/composables/usePackageComparison.ts:67–312  ·  view source on GitHub ↗
(packageNames: MaybeRefOrGetter<string[]>)

Source from the content-addressed store, hash-verified

65 *
66 */
67export function usePackageComparison(packageNames: MaybeRefOrGetter<string[]>) {
68 const { t } = useI18n()
69 const { $npmRegistry } = useNuxtApp()
70 const numberFormatter = useNumberFormatter()
71 const compactNumberFormatter = useCompactNumberFormatter()
72 const bytesFormatter = useBytesFormatter()
73 const packages = computed(() => toValue(packageNames))
74
75 // Cache of fetched data by package name (source of truth)
76 const cache = shallowRef(new Map<string, PackageComparisonData>())
77
78 // Derived array in current package order
79 const packagesData = computed(() => packages.value.map(name => cache.value.get(name) ?? null))
80
81 const status = shallowRef<'idle' | 'pending' | 'success' | 'error'>('idle')
82 const error = shallowRef<Error | null>(null)
83
84 // Track which packages are currently being fetched
85 const loadingPackages = shallowRef(new Set<string>())
86
87 // Track install size loading separately (it's slower)
88 const installSizeLoading = shallowRef(false)
89
90 // Fetch function - only fetches packages not already in cache
91 async function fetchPackages(names: string[]) {
92 if (names.length === 0) {
93 status.value = 'idle'
94 return
95 }
96
97 // Handle "no dependency" column - add to cache immediately
98 if (names.includes(NO_DEPENDENCY_ID) && !cache.value.has(NO_DEPENDENCY_ID)) {
99 const newCache = new Map(cache.value)
100 newCache.set(NO_DEPENDENCY_ID, createNoDependencyData())
101 cache.value = newCache
102 }
103
104 // Only fetch packages not already cached (excluding "no dep" which has no remote data)
105 const namesToFetch = names.filter(name => name !== NO_DEPENDENCY_ID && !cache.value.has(name))
106
107 if (namesToFetch.length === 0) {
108 status.value = 'success'
109 return
110 }
111
112 status.value = 'pending'
113 error.value = null
114
115 // Mark packages as loading
116 loadingPackages.value = new Set(namesToFetch)
117
118 try {
119 // First pass: fetch fast data (package info, downloads, analysis, vulns)
120 const results = await Promise.all(
121 namesToFetch.map(async (name): Promise<PackageComparisonData | null> => {
122 try {
123 // Fetch basic package info first (required)
124 const { data: pkgData } = await $npmRegistry<Packument>(`/${encodePackageName(name)}`)

Callers 1

setupFunction · 0.85

Calls 5

useNumberFormatterFunction · 0.85
useBytesFormatterFunction · 0.85
fetchPackagesFunction · 0.85
getMethod · 0.65

Tested by 1

setupFunction · 0.68