Skip to content

Commit 22ce764

Browse files
committed
Fix review comments
1 parent b11e4a0 commit 22ce764

File tree

6 files changed

+95
-49
lines changed

6 files changed

+95
-49
lines changed

app/components/Package/TrendsChart.vue

Lines changed: 31 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import { OKLCH_NEUTRAL_FALLBACK, transparentizeOklch } from '~/utils/colors'
77
import { getFrameworkColor, isListedFramework } from '~/utils/frameworks'
88
import { drawNpmxLogoAndTaglineWatermark } from '~/composables/useChartWatermark'
99
import type { RepoRef } from '#shared/utils/git-providers'
10-
import { parseRepoUrl } from '#shared/utils/git-providers'
11-
import type { PackageMetaResponse } from '#shared/types'
12-
import { encodePackageName } from '#shared/utils/npm'
1310
import type {
1411
ChartTimeGranularity,
1512
DailyDataPoint,
@@ -337,52 +334,28 @@ const effectivePackageNames = computed<string[]>(() => {
337334
return single ? [single] : []
338335
})
339336
340-
const repoRefsByPackage = shallowRef<Record<string, RepoRef | undefined>>({})
341-
const repoRefsRequestToken = shallowRef(0)
342-
343-
async function loadRepoRefsForPackages(packages: string[]) {
344-
if (!import.meta.client) return
345-
if (!packages.length) {
346-
repoRefsByPackage.value = {}
347-
return
348-
}
349-
350-
const currentToken = ++repoRefsRequestToken.value
351-
352-
const settled = await Promise.allSettled(
353-
packages.map(async name => {
354-
const encoded = encodePackageName(name)
355-
const meta = await $fetch<PackageMetaResponse>(`/api/registry/package-meta/${encoded}`)
356-
const repoUrl = meta?.links?.repository
357-
const ref = repoUrl ? parseRepoUrl(repoUrl) : undefined
358-
return { name, ref }
359-
}),
360-
)
361-
362-
if (currentToken !== repoRefsRequestToken.value) return
337+
const {
338+
fetchPackageDownloadEvolution,
339+
fetchPackageLikesEvolution,
340+
fetchRepoContributorsEvolution,
341+
fetchRepoRefsForPackages,
342+
} = useCharts()
363343
364-
const next: Record<string, RepoRef | undefined> = {}
365-
for (const [index, entry] of settled.entries()) {
366-
const name = packages[index]
367-
if (!name) continue
368-
if (entry.status === 'fulfilled') {
369-
next[name] = entry.value.ref ?? undefined
370-
} else {
371-
next[name] = undefined
372-
}
373-
}
374-
repoRefsByPackage.value = next
375-
}
344+
const repoRefsByPackage = shallowRef<Record<string, RepoRef | null>>({})
345+
const repoRefsRequestToken = shallowRef(0)
376346
377347
watch(
378348
() => effectivePackageNames.value,
379-
names => {
349+
async names => {
380350
if (!import.meta.client) return
381351
if (!isMultiPackageMode.value) {
382352
repoRefsByPackage.value = {}
383353
return
384354
}
385-
loadRepoRefsForPackages(names)
355+
const currentToken = ++repoRefsRequestToken.value
356+
const refs = await fetchRepoRefsForPackages(names)
357+
if (currentToken !== repoRefsRequestToken.value) return
358+
repoRefsByPackage.value = refs
386359
},
387360
{ immediate: true },
388361
)
@@ -626,18 +599,12 @@ function applyDateRange<T extends Record<string, unknown>>(base: T): T & DateRan
626599
return next
627600
}
628601
629-
const {
630-
fetchPackageDownloadEvolution,
631-
fetchPackageLikesEvolution,
632-
fetchRepoContributorsEvolution,
633-
} = useCharts()
634-
635602
type MetricId = 'downloads' | 'likes' | 'contributors'
636603
const DEFAULT_METRIC_ID: MetricId = 'downloads'
637604
638605
type MetricContext = {
639606
packageName: string
640-
repoRef?: RepoRef | undefined | null
607+
repoRef?: RepoRef | null
641608
}
642609
643610
type MetricDef = {
@@ -681,7 +648,7 @@ const METRICS = computed<MetricDef[]>(() => {
681648
id: 'contributors',
682649
label: $t('package.trends.items.contributors'),
683650
fetch: ({ repoRef }, opts) => fetchRepoContributorsEvolution(repoRef, opts),
684-
supportsMulti: false,
651+
supportsMulti: true,
685652
})
686653
}
687654
@@ -700,6 +667,16 @@ const effectivePackageNamesForMetric = computed<string[]>(() => {
700667
)
701668
})
702669
670+
const skippedPackagesWithoutGitHub = computed(() => {
671+
if (!isMultiPackageMode.value) return []
672+
if (selectedMetric.value !== 'contributors') return []
673+
if (!effectivePackageNames.value.length) return []
674+
675+
return effectivePackageNames.value.filter(
676+
name => repoRefsByPackage.value[name]?.provider !== 'github',
677+
)
678+
})
679+
703680
const availableGranularities = computed<ChartTimeGranularity[]>(() => {
704681
if (selectedMetric.value === 'contributors') {
705682
return ['weekly', 'monthly', 'yearly']
@@ -856,7 +833,7 @@ async function loadMetric(metricId: MetricId) {
856833
857834
const settled = await Promise.allSettled(
858835
packageNames.map(async pkg => {
859-
const repoRef = metricId === 'contributors' ? repoRefsByPackage.value[pkg] : undefined
836+
const repoRef = metricId === 'contributors' ? repoRefsByPackage.value[pkg] : null
860837
const result = await fetchFn({ packageName: pkg, repoRef })
861838
return { pkg, result: (result ?? []) as EvolutionData }
862839
}),
@@ -1692,6 +1669,11 @@ watch(selectedMetric, value => {
16921669
<span class="i-carbon:reset w-5 h-5" aria-hidden="true" />
16931670
</button>
16941671
</div>
1672+
1673+
<p v-if="skippedPackagesWithoutGitHub.length > 0" class="text-2xs font-mono text-fg-subtle">
1674+
{{ $t('package.trends.contributors_skip', { count: skippedPackagesWithoutGitHub.length }) }}
1675+
{{ skippedPackagesWithoutGitHub.join(', ') }}
1676+
</p>
16951677
</div>
16961678

16971679
<h2 id="trends-chart-title" class="sr-only">

app/composables/useCharts.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import type {
99
YearlyDataPoint,
1010
} from '~/types/chart'
1111
import type { RepoRef } from '#shared/utils/git-providers'
12+
import { parseRepoUrl } from '#shared/utils/git-providers'
13+
import type { PackageMetaResponse } from '#shared/types'
14+
import { encodePackageName } from '#shared/utils/npm'
1215
import { fetchNpmDownloadsRange } from '~/utils/npm/api'
1316

1417
export type PackumentLikeForTime = {
@@ -186,12 +189,14 @@ const likesEvolutionCache = import.meta.client ? new Map<string, Promise<DailyRa
186189
const contributorsEvolutionCache = import.meta.client
187190
? new Map<string, Promise<GitHubContributorStats[]>>()
188191
: null
192+
const repoMetaCache = import.meta.client ? new Map<string, Promise<RepoRef | null>>() : null
189193

190194
/** Clears client-side promise caches. Exported for use in tests. */
191195
export function clearClientCaches() {
192196
npmDailyRangeCache?.clear()
193197
likesEvolutionCache?.clear()
194198
contributorsEvolutionCache?.clear()
199+
repoMetaCache?.clear()
195200
}
196201

197202
type GitHubContributorWeek = {
@@ -563,10 +568,63 @@ export function useCharts() {
563568
return []
564569
}
565570

571+
async function fetchRepoRefsForPackages(
572+
packageNames: MaybeRefOrGetter<string[]>,
573+
): Promise<Record<string, RepoRef | null>> {
574+
const names = (toValue(packageNames) ?? []).map(n => String(n).trim()).filter(Boolean)
575+
if (!import.meta.client || !names.length) return {}
576+
577+
const settled = await Promise.allSettled(
578+
names.map(async name => {
579+
const cacheKey = name
580+
const cache = repoMetaCache
581+
if (cache?.has(cacheKey)) {
582+
const ref = await cache.get(cacheKey)!
583+
return { name, ref }
584+
}
585+
586+
const promise = $fetch<PackageMetaResponse>(
587+
`/api/registry/package-meta/${encodePackageName(name)}`,
588+
)
589+
.then(meta => {
590+
console.log('name', name)
591+
if (name === 'create-cedar-app') {
592+
console.log('create-cedar-app returns null')
593+
return null
594+
}
595+
const repoUrl = meta?.links?.repository
596+
return repoUrl ? parseRepoUrl(repoUrl) : null
597+
})
598+
.catch(error => {
599+
cache?.delete(cacheKey)
600+
throw error
601+
})
602+
603+
cache?.set(cacheKey, promise)
604+
const ref = await promise
605+
return { name, ref }
606+
}),
607+
)
608+
609+
const next: Record<string, RepoRef | null> = {}
610+
for (const [index, entry] of settled.entries()) {
611+
const name = names[index]
612+
if (!name) continue
613+
if (entry.status === 'fulfilled') {
614+
next[name] = entry.value.ref ?? null
615+
} else {
616+
next[name] = null
617+
}
618+
}
619+
620+
return next
621+
}
622+
566623
return {
567624
fetchPackageDownloadEvolution,
568625
fetchPackageLikesEvolution,
569626
fetchRepoContributorsEvolution,
627+
fetchRepoRefsForPackages,
570628
getNpmPackageCreationDate,
571629
}
572630
}

i18n/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@
351351
"y_axis_label": "{granularity} {facet}",
352352
"facet": "Facet",
353353
"title": "Trends",
354+
"contributors_skip": "Not shown in Contributors (no GitHub repo):",
354355
"items": {
355356
"downloads": "Downloads",
356357
"likes": "Likes",

i18n/schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,9 @@
10571057
"title": {
10581058
"type": "string"
10591059
},
1060+
"contributors_skip": {
1061+
"type": "string"
1062+
},
10601063
"items": {
10611064
"type": "object",
10621065
"properties": {

lunaria/files/en-GB.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@
350350
"y_axis_label": "{granularity} {facet}",
351351
"facet": "Facet",
352352
"title": "Trends",
353+
"contributors_skip": "Not shown in Contributors (no GitHub repo):",
353354
"items": {
354355
"downloads": "Downloads",
355356
"likes": "Likes",

lunaria/files/en-US.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@
350350
"y_axis_label": "{granularity} {facet}",
351351
"facet": "Facet",
352352
"title": "Trends",
353+
"contributors_skip": "Not shown in Contributors (no GitHub repo):",
353354
"items": {
354355
"downloads": "Downloads",
355356
"likes": "Likes",

0 commit comments

Comments
 (0)