From e2a5537b36ac0cfd0accd3d203d56a009bd583d6 Mon Sep 17 00:00:00 2001 From: Sukiu <17344148+Sukiiu@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:21:19 +0200 Subject: [PATCH 1/5] feat: compare by likes --- app/composables/usePackageComparison.ts | 18 ++++++++++++++++-- i18n/locales/en.json | 3 +++ lunaria/files/en-GB.json | 3 +++ lunaria/files/en-US.json | 3 +++ shared/types/comparison.ts | 4 ++++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/composables/usePackageComparison.ts b/app/composables/usePackageComparison.ts index 690bff4da..49fdbd671 100644 --- a/app/composables/usePackageComparison.ts +++ b/app/composables/usePackageComparison.ts @@ -44,6 +44,8 @@ export interface PackageComparisonData { } /** Whether this is a binary-only package (CLI without library entry points) */ isBinaryOnly?: boolean + /** Total likes from atproto */ + totalLikes: number } /** @@ -104,7 +106,7 @@ export function usePackageComparison(packageNames: MaybeRefOrGetter) { if (!latestVersion) return null // Fetch fast additional data in parallel (optional - failures are ok) - const [downloads, analysis, vulns] = await Promise.all([ + const [downloads, analysis, vulns, likes] = await Promise.all([ $fetch<{ downloads: number }>( `https://api.npmjs.org/downloads/point/last-week/${encodePackageName(name)}`, ).catch(() => null), @@ -112,8 +114,11 @@ export function usePackageComparison(packageNames: MaybeRefOrGetter) { $fetch(`/api/registry/vulnerabilities/${name}`).catch( () => null, ), + $fetch(`/api/social/likes/${name}`).catch(() => ({ + totalLikes: 0, + userHasLiked: false, + })), ]) - const versionData = pkgData.versions[latestVersion] const packageSize = versionData?.dist?.unpackedSize @@ -160,6 +165,7 @@ export function usePackageComparison(packageNames: MaybeRefOrGetter) { deprecated: versionData?.deprecated, }, isBinaryOnly: isBinary, + totalLikes: likes.totalLikes, } } catch { return null @@ -384,6 +390,14 @@ function computeFacetValue( status: isDeprecated ? 'bad' : 'good', } } + case 'totalLikes': { + if (data.totalLikes === undefined) return null + return { + raw: data.totalLikes, + display: formatCompactNumber(data.totalLikes), + status: 'neutral', + } + } // Coming soon facets case 'totalDependencies': { if (!data.installSize) return null diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 7518b487c..7f40c2b1c 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -935,6 +935,9 @@ "vulnerabilities": { "label": "Vulnerabilities", "description": "Known security vulnerabilities" + }, + "totalLikes": { + "label": "Likes" } }, "values": { diff --git a/lunaria/files/en-GB.json b/lunaria/files/en-GB.json index 583ca875d..b072674b7 100644 --- a/lunaria/files/en-GB.json +++ b/lunaria/files/en-GB.json @@ -935,6 +935,9 @@ "vulnerabilities": { "label": "Vulnerabilities", "description": "Known security vulnerabilities" + }, + "totalLikes": { + "label": "Likes" } }, "values": { diff --git a/lunaria/files/en-US.json b/lunaria/files/en-US.json index 7518b487c..7f40c2b1c 100644 --- a/lunaria/files/en-US.json +++ b/lunaria/files/en-US.json @@ -935,6 +935,9 @@ "vulnerabilities": { "label": "Vulnerabilities", "description": "Known security vulnerabilities" + }, + "totalLikes": { + "label": "Likes" } }, "values": { diff --git a/shared/types/comparison.ts b/shared/types/comparison.ts index ec3113f0f..6bc25c8a0 100644 --- a/shared/types/comparison.ts +++ b/shared/types/comparison.ts @@ -16,6 +16,7 @@ export type ComparisonFacet = | 'dependencies' | 'totalDependencies' | 'deprecated' + | 'totalLikes' /** Facet metadata for UI display */ export interface FacetInfo { @@ -52,6 +53,9 @@ export const FACET_INFO: Record> = { deprecated: { category: 'health', }, + totalLikes: { + category: 'health', + }, // Compatibility engines: { category: 'compatibility', From b63e1ea623a3cbea8de81c9f03f863e9bb98b675 Mon Sep 17 00:00:00 2001 From: Sukiu <17344148+Sukiiu@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:28:07 +0200 Subject: [PATCH 2/5] fix: move next to down/weeks --- app/composables/usePackageComparison.ts | 20 ++++++++++---------- i18n/locales/en.json | 7 ++++--- i18n/locales/fr-FR.json | 4 ++++ lunaria/files/en-GB.json | 7 ++++--- lunaria/files/en-US.json | 7 ++++--- lunaria/files/fr-FR.json | 4 ++++ shared/types/comparison.ts | 6 +++--- 7 files changed, 33 insertions(+), 22 deletions(-) diff --git a/app/composables/usePackageComparison.ts b/app/composables/usePackageComparison.ts index 49fdbd671..345109cdc 100644 --- a/app/composables/usePackageComparison.ts +++ b/app/composables/usePackageComparison.ts @@ -14,6 +14,8 @@ import { getDependencyCount } from '~/utils/npm/dependency-count' export interface PackageComparisonData { package: ComparisonPackage downloads?: number + /** Total likes from atproto */ + totalLikes: number /** Package's own unpacked size (from dist.unpackedSize) */ packageSize?: number /** Number of direct dependencies */ @@ -44,8 +46,6 @@ export interface PackageComparisonData { } /** Whether this is a binary-only package (CLI without library entry points) */ isBinaryOnly?: boolean - /** Total likes from atproto */ - totalLikes: number } /** @@ -275,6 +275,14 @@ function computeFacetValue( status: 'neutral', } } + case 'totalLikes': { + if (data.totalLikes === undefined) return null + return { + raw: data.totalLikes, + display: formatCompactNumber(data.totalLikes), + status: 'neutral', + } + } case 'packageSize': { if (!data.packageSize) return null return { @@ -390,14 +398,6 @@ function computeFacetValue( status: isDeprecated ? 'bad' : 'good', } } - case 'totalLikes': { - if (data.totalLikes === undefined) return null - return { - raw: data.totalLikes, - display: formatCompactNumber(data.totalLikes), - status: 'neutral', - } - } // Coming soon facets case 'totalDependencies': { if (!data.installSize) return null diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 7f40c2b1c..3077eeb83 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -908,6 +908,10 @@ "label": "Downloads/wk", "description": "Weekly download count" }, + "totalLikes": { + "label": "Likes", + "description": "Number of likes" + }, "lastUpdated": { "label": "Published", "description": "When this version was published" @@ -935,9 +939,6 @@ "vulnerabilities": { "label": "Vulnerabilities", "description": "Known security vulnerabilities" - }, - "totalLikes": { - "label": "Likes" } }, "values": { diff --git a/i18n/locales/fr-FR.json b/i18n/locales/fr-FR.json index 6bfaa114e..2b3e34c3b 100644 --- a/i18n/locales/fr-FR.json +++ b/i18n/locales/fr-FR.json @@ -891,6 +891,10 @@ "label": "Téléch./semaine", "description": "Nombre de téléchargements par semaine" }, + "totalLikes": { + "label": "Likes", + "description": "Nombre de likes" + }, "lastUpdated": { "label": "Publié", "description": "Quand cette version a été publiée" diff --git a/lunaria/files/en-GB.json b/lunaria/files/en-GB.json index b072674b7..d84d57e08 100644 --- a/lunaria/files/en-GB.json +++ b/lunaria/files/en-GB.json @@ -908,6 +908,10 @@ "label": "Downloads/wk", "description": "Weekly download count" }, + "totalLikes": { + "label": "Likes", + "description": "Number of likes" + }, "lastUpdated": { "label": "Published", "description": "When this version was published" @@ -935,9 +939,6 @@ "vulnerabilities": { "label": "Vulnerabilities", "description": "Known security vulnerabilities" - }, - "totalLikes": { - "label": "Likes" } }, "values": { diff --git a/lunaria/files/en-US.json b/lunaria/files/en-US.json index 7f40c2b1c..3077eeb83 100644 --- a/lunaria/files/en-US.json +++ b/lunaria/files/en-US.json @@ -908,6 +908,10 @@ "label": "Downloads/wk", "description": "Weekly download count" }, + "totalLikes": { + "label": "Likes", + "description": "Number of likes" + }, "lastUpdated": { "label": "Published", "description": "When this version was published" @@ -935,9 +939,6 @@ "vulnerabilities": { "label": "Vulnerabilities", "description": "Known security vulnerabilities" - }, - "totalLikes": { - "label": "Likes" } }, "values": { diff --git a/lunaria/files/fr-FR.json b/lunaria/files/fr-FR.json index 6bfaa114e..2b3e34c3b 100644 --- a/lunaria/files/fr-FR.json +++ b/lunaria/files/fr-FR.json @@ -891,6 +891,10 @@ "label": "Téléch./semaine", "description": "Nombre de téléchargements par semaine" }, + "totalLikes": { + "label": "Likes", + "description": "Nombre de likes" + }, "lastUpdated": { "label": "Publié", "description": "Quand cette version a été publiée" diff --git a/shared/types/comparison.ts b/shared/types/comparison.ts index 6bc25c8a0..9dfe229eb 100644 --- a/shared/types/comparison.ts +++ b/shared/types/comparison.ts @@ -47,13 +47,13 @@ export const FACET_INFO: Record> = { downloads: { category: 'health', }, - lastUpdated: { + totalLikes: { category: 'health', }, - deprecated: { + lastUpdated: { category: 'health', }, - totalLikes: { + deprecated: { category: 'health', }, // Compatibility From f87f35abf60ad1cdcd5760878f4e64e22ff0948b Mon Sep 17 00:00:00 2001 From: Sukiu <17344148+Sukiiu@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:44:47 +0200 Subject: [PATCH 3/5] fix: missing import --- app/composables/usePackageComparison.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/app/composables/usePackageComparison.ts b/app/composables/usePackageComparison.ts index 345109cdc..8cc4d9d75 100644 --- a/app/composables/usePackageComparison.ts +++ b/app/composables/usePackageComparison.ts @@ -5,6 +5,7 @@ import type { Packument, VulnerabilityTreeResult, } from '#shared/types' +import type { PackageLikes } from '#shared/types/social' import { encodePackageName } from '#shared/utils/npm' import type { PackageAnalysisResponse } from './usePackageAnalysis' import { isBinaryOnlyPackage } from '#shared/utils/binary-detection' From 6960685b6af71ea9af981edfd1c7c7a6dd072f81 Mon Sep 17 00:00:00 2001 From: Sukiu <17344148+Sukiiu@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:52:29 +0200 Subject: [PATCH 4/5] fix: follow the same failure pattern --- app/composables/usePackageComparison.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/app/composables/usePackageComparison.ts b/app/composables/usePackageComparison.ts index 8cc4d9d75..444914650 100644 --- a/app/composables/usePackageComparison.ts +++ b/app/composables/usePackageComparison.ts @@ -16,7 +16,7 @@ export interface PackageComparisonData { package: ComparisonPackage downloads?: number /** Total likes from atproto */ - totalLikes: number + totalLikes?: number /** Package's own unpacked size (from dist.unpackedSize) */ packageSize?: number /** Number of direct dependencies */ @@ -115,10 +115,7 @@ export function usePackageComparison(packageNames: MaybeRefOrGetter) { $fetch(`/api/registry/vulnerabilities/${name}`).catch( () => null, ), - $fetch(`/api/social/likes/${name}`).catch(() => ({ - totalLikes: 0, - userHasLiked: false, - })), + $fetch(`/api/social/likes/${name}`).catch(() => null), ]) const versionData = pkgData.versions[latestVersion] const packageSize = versionData?.dist?.unpackedSize @@ -166,7 +163,7 @@ export function usePackageComparison(packageNames: MaybeRefOrGetter) { deprecated: versionData?.deprecated, }, isBinaryOnly: isBinary, - totalLikes: likes.totalLikes, + totalLikes: likes?.totalLikes, } } catch { return null From acbb010bd992daf6eb8d39dcdd716b7ff2dd90f2 Mon Sep 17 00:00:00 2001 From: Sukiu <17344148+Sukiiu@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:53:25 +0200 Subject: [PATCH 5/5] fix(test): add totalLikes facet label --- test/nuxt/components/compare/FacetSelector.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/nuxt/components/compare/FacetSelector.spec.ts b/test/nuxt/components/compare/FacetSelector.spec.ts index 6d98e87ae..9dc2757e6 100644 --- a/test/nuxt/components/compare/FacetSelector.spec.ts +++ b/test/nuxt/components/compare/FacetSelector.spec.ts @@ -31,6 +31,7 @@ const facetLabels: Record = {