Skip to content

Commit 9d4976e

Browse files
committed
perf: use fast-npm-meta for resolving package version
1 parent fe73494 commit 9d4976e

2 files changed

Lines changed: 48 additions & 57 deletions

File tree

app/composables/useNpmRegistry.ts

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ import type {
88
NpmPerson,
99
PackageVersionInfo,
1010
} from '#shared/types'
11-
import type { PackageVersionsInfoWithMetadata } from 'fast-npm-meta'
11+
import type { PackageVersionsInfoWithMetadata, ResolvedPackageVersion } from 'fast-npm-meta'
1212
import type { ReleaseType } from 'semver'
1313
import { mapWithConcurrency } from '#shared/utils/async'
1414
import { maxSatisfying, prerelease, major, minor, diff, gt, compare } from 'semver'
15-
import { isExactVersion } from '~/utils/versions'
1615
import { extractInstallScriptsInfo } from '~/utils/install-scripts'
1716
import type { CachedFetchFunction } from '#shared/utils/fetch-cache-config'
1817
import { FAST_NPM_META_API, encodePackageName } from '#shared/utils/npm'
@@ -172,6 +171,23 @@ function transformPackument(pkg: Packument, requestedVersion?: string | null): S
172171
}
173172
}
174173

174+
export function useResolvedVersion(
175+
packageName: MaybeRefOrGetter<string>,
176+
requestedVersion: MaybeRefOrGetter<string | null>,
177+
) {
178+
return useFetch(
179+
() => {
180+
const version = toValue(requestedVersion)
181+
return version
182+
? `https://npm.antfu.dev/${toValue(packageName)}@${version}`
183+
: `https://npm.antfu.dev/${toValue(packageName)}`
184+
},
185+
{
186+
transform: (data: ResolvedPackageVersion) => data.version,
187+
},
188+
)
189+
}
190+
175191
export function usePackage(
176192
name: MaybeRefOrGetter<string>,
177193
requestedVersion?: MaybeRefOrGetter<string | null>,
@@ -187,8 +203,7 @@ export function usePackage(
187203
})
188204
const reqVer = toValue(requestedVersion)
189205
const pkg = transformPackument(r, reqVer)
190-
const resolvedVersion = getResolvedVersion(pkg, reqVer)
191-
return { ...pkg, resolvedVersion, isStale }
206+
return { ...pkg, isStale }
192207
},
193208
)
194209

@@ -201,26 +216,6 @@ export function usePackage(
201216
return asyncData
202217
}
203218

204-
function getResolvedVersion(pkg: SlimPackument, reqVer?: string | null): string | null {
205-
if (!pkg || !reqVer) return null
206-
207-
// 1. Check if it's already an exact version in pkg.versions
208-
if (isExactVersion(reqVer) && pkg.versions[reqVer]) {
209-
return reqVer
210-
}
211-
212-
// 2. Check if it's a dist-tag (latest, next, beta, etc.)
213-
const tagVersion = pkg['dist-tags']?.[reqVer]
214-
if (tagVersion) {
215-
return tagVersion
216-
}
217-
218-
// 3. Try to resolve as a semver range
219-
const versions = Object.keys(pkg.versions)
220-
const resolved = maxSatisfying(versions, reqVer)
221-
return resolved
222-
}
223-
224219
export function usePackageDownloads(
225220
name: MaybeRefOrGetter<string>,
226221
period: MaybeRefOrGetter<'last-day' | 'last-week' | 'last-month' | 'last-year'> = 'last-week',

app/pages/[...package].vue

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ const { data: skillsData } = useLazyFetch<SkillsListResponse>(
104104
const { data: packageAnalysis } = usePackageAnalysis(packageName, requestedVersion)
105105
const { data: moduleReplacement } = useModuleReplacement(packageName)
106106
107-
const { data: pkg, status, error } = await usePackage(packageName, requestedVersion)
108-
const resolvedVersion = computed(() => pkg.value?.resolvedVersion ?? null)
107+
const { data: resolvedVersion } = await useResolvedVersion(packageName, requestedVersion)
108+
const { data: pkg, status, error } = usePackage(packageName, requestedVersion)
109109
110110
// Get the version to display (resolved version or latest)
111111
const displayVersion = computed(() => {
@@ -138,7 +138,7 @@ const { copied: copiedPkgName, copy: copyPkgName } = useClipboard({
138138
// This is the same composable used by PackageVulnerabilityTree and PackageDeprecatedTree
139139
const { data: vulnTree, status: vulnTreeStatus } = useDependencyAnalysis(
140140
packageName,
141-
() => displayVersion.value?.version ?? '',
141+
() => resolvedVersion.value ?? '',
142142
)
143143
144144
// Keep latestVersion for comparison (to show "(latest)" badge)
@@ -261,12 +261,12 @@ const homepageUrl = computed(() => {
261261
262262
// Docs URL: use our generated API docs
263263
const docsLink = computed(() => {
264-
if (!displayVersion.value) return null
264+
if (!resolvedVersion.value) return null
265265
266266
return {
267267
name: 'docs' as const,
268268
params: {
269-
path: [...pkg.value!.name.split('/'), 'v', displayVersion.value.version],
269+
path: [...pkg.value!.name.split('/'), 'v', resolvedVersion.value],
270270
},
271271
}
272272
})
@@ -360,12 +360,12 @@ useSeoMeta({
360360
onKeyStroke(
361361
e => isKeyWithoutModifiers(e, '.') && !isEditableElement(e.target),
362362
e => {
363-
if (pkg.value == null || displayVersion.value == null) return
363+
if (pkg.value == null || resolvedVersion.value == null) return
364364
e.preventDefault()
365365
navigateTo({
366366
name: 'code',
367367
params: {
368-
path: [pkg.value.name, 'v', displayVersion.value.version],
368+
path: [pkg.value.name, 'v', resolvedVersion.value],
369369
},
370370
})
371371
},
@@ -393,7 +393,7 @@ onKeyStroke(
393393
394394
defineOgImageComponent('Package', {
395395
name: () => pkg.value?.name ?? 'Package',
396-
version: () => displayVersion.value?.version ?? '',
396+
version: () => resolvedVersion.value ?? '',
397397
downloads: () => (downloads.value ? $n(downloads.value.downloads) : ''),
398398
license: () => pkg.value?.license ?? '',
399399
stars: () => stars.value ?? 0,
@@ -455,26 +455,26 @@ function handleClick(event: MouseEvent) {
455455

456456
<span id="copy-pkg-name" class="sr-only">{{ $t('package.copy_name') }}</span>
457457
<span
458-
v-if="displayVersion"
458+
v-if="resolvedVersion"
459459
class="inline-flex items-baseline gap-1.5 font-mono text-base sm:text-lg text-fg-muted shrink-0"
460460
>
461461
<!-- Version resolution indicator (e.g., "latest → 4.2.0") -->
462-
<template v-if="resolvedVersion !== requestedVersion">
462+
<template v-if="requestedVersion && resolvedVersion !== requestedVersion">
463463
<span class="font-mono text-fg-muted text-sm">{{ requestedVersion }}</span>
464464
<span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" />
465465
</template>
466466

467467
<NuxtLink
468-
v-if="resolvedVersion !== requestedVersion"
469-
:to="`/${pkg.name}/v/${displayVersion.version}`"
468+
v-if="requestedVersion && resolvedVersion !== requestedVersion"
469+
:to="`/${pkg.name}/v/${resolvedVersion}`"
470470
:title="$t('package.view_permalink')"
471-
>{{ displayVersion.version }}</NuxtLink
471+
>{{ resolvedVersion }}</NuxtLink
472472
>
473-
<span v-else>v{{ displayVersion.version }}</span>
473+
<span v-else>v{{ resolvedVersion }}</span>
474474

475475
<a
476476
v-if="hasProvenance(displayVersion)"
477-
:href="`https://www.npmjs.com/package/${pkg.name}/v/${displayVersion.version}#provenance`"
477+
:href="`https://www.npmjs.com/package/${pkg.name}/v/${resolvedVersion}#provenance`"
478478
target="_blank"
479479
rel="noopener noreferrer"
480480
class="inline-flex items-center justify-center gap-1.5 text-fg-muted hover:text-fg transition-colors duration-200 min-w-6 min-h-6"
@@ -483,11 +483,7 @@ function handleClick(event: MouseEvent) {
483483
<span class="i-solar:shield-check-outline w-3.5 h-3.5 shrink-0" aria-hidden="true" />
484484
</a>
485485
<span
486-
v-if="
487-
requestedVersion &&
488-
latestVersion &&
489-
displayVersion.version !== latestVersion.version
490-
"
486+
v-if="requestedVersion && latestVersion && resolvedVersion !== latestVersion.version"
491487
class="text-fg-subtle text-sm shrink-0"
492488
>{{ $t('package.not_latest') }}</span
493489
>
@@ -496,9 +492,9 @@ function handleClick(event: MouseEvent) {
496492
<!-- Package metrics (module format, types) -->
497493
<ClientOnly>
498494
<PackageMetricsBadges
499-
v-if="displayVersion"
495+
v-if="resolvedVersion"
500496
:package-name="pkg.name"
501-
:version="displayVersion.version"
497+
:version="resolvedVersion"
502498
:is-binary="isBinaryOnly"
503499
class="self-baseline ms-1 sm:ms-2"
504500
/>
@@ -512,7 +508,7 @@ function handleClick(event: MouseEvent) {
512508

513509
<!-- Internal navigation: Docs + Code + Compare (hidden on mobile, shown in external links instead) -->
514510
<nav
515-
v-if="displayVersion"
511+
v-if="resolvedVersion"
516512
:aria-label="$t('package.navigation')"
517513
class="hidden sm:flex items-center gap-0.5 p-0.5 bg-bg-subtle border border-border-subtle rounded-md shrink-0 ms-auto self-center"
518514
>
@@ -535,7 +531,7 @@ function handleClick(event: MouseEvent) {
535531
:to="{
536532
name: 'code',
537533
params: {
538-
path: [...pkg.name.split('/'), 'v', displayVersion.version],
534+
path: [...pkg.name.split('/'), 'v', resolvedVersion],
539535
},
540536
}"
541537
class="px-2 py-1.5 font-mono text-xs rounded transition-colors duration-150 border border-transparent text-fg-subtle hover:text-fg hover:bg-bg hover:shadow hover:border-border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50 inline-flex items-center gap-1.5"
@@ -686,12 +682,12 @@ function handleClick(event: MouseEvent) {
686682
{{ $t('package.links.docs') }}
687683
</NuxtLink>
688684
</li>
689-
<li v-if="displayVersion" class="sm:hidden">
685+
<li v-if="resolvedVersion" class="sm:hidden">
690686
<NuxtLink
691687
:to="{
692688
name: 'code',
693689
params: {
694-
path: [...pkg.name.split('/'), 'v', displayVersion.version],
690+
path: [...pkg.name.split('/'), 'v', resolvedVersion],
695691
},
696692
}"
697693
class="link-subtle font-mono text-sm inline-flex items-center gap-1.5"
@@ -789,7 +785,7 @@ function handleClick(event: MouseEvent) {
789785

790786
<a
791787
v-if="getDependencyCount(displayVersion) > 0"
792-
:href="`https://node-modules.dev/grid/depth#install=${pkg.name}${displayVersion?.version ? `@${displayVersion.version}` : ''}`"
788+
:href="`https://node-modules.dev/grid/depth#install=${pkg.name}${resolvedVersion ? `@${resolvedVersion}` : ''}`"
793789
target="_blank"
794790
rel="noopener noreferrer"
795791
class="text-fg-subtle hover:text-fg transition-colors duration-200 inline-flex items-center justify-center min-w-6 min-h-6 -m-1 p-1"
@@ -959,14 +955,14 @@ function handleClick(event: MouseEvent) {
959955
<!-- Vulnerability scan -->
960956
<ClientOnly>
961957
<PackageVulnerabilityTree
962-
v-if="displayVersion"
958+
v-if="resolvedVersion"
963959
:package-name="pkg.name"
964-
:version="displayVersion.version"
960+
:version="resolvedVersion"
965961
/>
966962
<PackageDeprecatedTree
967-
v-if="displayVersion"
963+
v-if="resolvedVersion"
968964
:package-name="pkg.name"
969-
:version="displayVersion.version"
965+
:version="resolvedVersion"
970966
class="mt-3"
971967
/>
972968
</ClientOnly>
@@ -1108,9 +1104,9 @@ function handleClick(event: MouseEvent) {
11081104

11091105
<!-- Dependencies -->
11101106
<PackageDependencies
1111-
v-if="hasDependencies && displayVersion"
1107+
v-if="hasDependencies && resolvedVersion && displayVersion"
11121108
:package-name="pkg.name"
1113-
:version="displayVersion.version"
1109+
:version="resolvedVersion"
11141110
:dependencies="displayVersion.dependencies"
11151111
:peer-dependencies="displayVersion.peerDependencies"
11161112
:peer-dependencies-meta="displayVersion.peerDependenciesMeta"

0 commit comments

Comments
 (0)