@@ -67,6 +67,37 @@ const { data: jsrInfo } = useLazyFetch<JsrPackageInfo>(() => `/api/jsr/${package
6767 immediate: computed (() => packageName .value .startsWith (' @' )).value ,
6868})
6969
70+ // Fetch total install size (lazy, can be slow for large dependency trees)
71+ interface InstallSizeResult {
72+ package: string
73+ version: string
74+ selfSize: number
75+ totalSize: number
76+ dependencyCount: number
77+ }
78+ const { data : installSize, status : installSizeStatus } = useLazyFetch <InstallSizeResult | null >(
79+ () => {
80+ const base = ` /api/registry/install-size/${packageName .value } `
81+ const version = requestedVersion .value
82+ return version ? ` ${base }/v/${version } ` : base
83+ },
84+ {
85+ server: false ,
86+ },
87+ )
88+
89+ const sizeTooltip = computed (() => {
90+ const chunks = [
91+ displayVersion .value &&
92+ displayVersion .value .dist .unpackedSize &&
93+ ` ${formatBytes (displayVersion .value .dist .unpackedSize )} unpacked size (this package) ` ,
94+ installSize .value &&
95+ installSize .value .dependencyCount &&
96+ ` ${formatBytes (installSize .value .totalSize )} total unpacked size (including all ${installSize .value .dependencyCount } dependencies for linux-x64) ` ,
97+ ]
98+ return chunks .filter (Boolean ).join (' \n ' )
99+ })
100+
70101// Get the version to display (requested or latest)
71102const displayVersion = computed (() => {
72103 if (! pkg .value ) return null
@@ -93,7 +124,12 @@ const hasDependencies = computed(() => {
93124 if (! displayVersion .value ) return false
94125 const deps = displayVersion .value .dependencies
95126 const peerDeps = displayVersion .value .peerDependencies
96- return (deps && Object .keys (deps ).length > 0 ) || (peerDeps && Object .keys (peerDeps ).length > 0 )
127+ const optionalDeps = displayVersion .value .optionalDependencies
128+ return (
129+ (deps && Object .keys (deps ).length > 0 ) ||
130+ (peerDeps && Object .keys (peerDeps ).length > 0 ) ||
131+ (optionalDeps && Object .keys (optionalDeps ).length > 0 )
132+ )
97133})
98134
99135const repositoryUrl = computed (() => {
@@ -353,23 +389,6 @@ defineOgImageComponent('Package', {
353389 </dd >
354390 </div >
355391
356- <div v-if =" displayVersion?.dist?.unpackedSize" class =" space-y-1" >
357- <dt class =" text-xs text-fg-subtle uppercase tracking-wider" >Size</dt >
358- <dd class =" font-mono text-sm text-fg flex items-baseline justify-start gap-2" >
359- {{ formatBytes(displayVersion.dist.unpackedSize) }}
360- <a
361- :href =" `https://pkg-size.dev/${pkg.name}`"
362- target =" _blank"
363- rel =" noopener noreferrer"
364- class =" text-fg-subtle hover:text-fg transition-colors duration-200"
365- title =" View bundle size analysis"
366- >
367- <span class =" i-carbon-launch w-3.5 h-3.5 inline-block" aria-hidden =" true" />
368- <span class =" sr-only" >View bundle size analysis</span >
369- </a >
370- </dd >
371- </div >
372-
373392 <div v-if =" getDependencyCount(displayVersion) > 0" class =" space-y-1" >
374393 <dt class =" text-xs text-fg-subtle uppercase tracking-wider" >Deps</dt >
375394 <dd class =" font-mono text-sm text-fg flex items-baseline justify-start gap-2" >
@@ -387,7 +406,41 @@ defineOgImageComponent('Package', {
387406 </dd >
388407 </div >
389408
390- <div v-if =" pkg.time?.modified" class =" space-y-1 col-span-2" >
409+ <div class =" space-y-1 col-span-2" >
410+ <dt class =" text-xs text-fg-subtle uppercase tracking-wider flex items-center gap-1" >
411+ Install Size
412+ <span
413+ class =" i-carbon-information w-3 h-3 text-fg-subtle"
414+ aria-hidden =" true"
415+ :title =" sizeTooltip"
416+ />
417+ </dt >
418+ <dd class =" font-mono text-sm text-fg" >
419+ <!-- Package size (greyed out) -->
420+ <span class =" text-fg-muted" >
421+ <span v-if =" displayVersion?.dist?.unpackedSize" >
422+ {{ formatBytes(displayVersion.dist.unpackedSize) }}
423+ </span >
424+ <span v-else >-</span >
425+ </span >
426+
427+ <!-- Separator and install size -->
428+ <span class =" text-fg-subtle mx-1" >/</span >
429+
430+ <span
431+ v-if =" installSizeStatus === 'pending'"
432+ class =" inline-flex items-center gap-1 text-fg-subtle"
433+ >
434+ <span class =" i-carbon-circle-dash w-3 h-3 animate-spin" aria-hidden =" true" />
435+ </span >
436+ <span v-else-if =" installSize?.totalSize" >
437+ {{ formatBytes(installSize.totalSize) }}
438+ </span >
439+ <span v-else class =" text-fg-subtle" >-</span >
440+ </dd >
441+ </div >
442+
443+ <div v-if =" pkg.time?.modified" class =" space-y-1" >
391444 <dt class =" text-xs text-fg-subtle uppercase tracking-wider" >Updated</dt >
392445 <dd class =" font-mono text-sm text-fg" >
393446 <time :datetime =" pkg.time.modified" >{{ formatDate(pkg.time.modified) }}</time >
@@ -664,6 +717,7 @@ defineOgImageComponent('Package', {
664717 :dependencies =" displayVersion?.dependencies"
665718 :peer-dependencies =" displayVersion?.peerDependencies"
666719 :peer-dependencies-meta =" displayVersion?.peerDependenciesMeta"
720+ :optional-dependencies =" displayVersion?.optionalDependencies"
667721 />
668722 </aside >
669723 </div >
0 commit comments