Skip to content

Commit 5343fac

Browse files
committed
feat: use map to avoid O(n) searching
1 parent 71a566c commit 5343fac

1 file changed

Lines changed: 81 additions & 89 deletions

File tree

app/pages/package/[[org]]/[name]/versions.vue

Lines changed: 81 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@ const sortedVersions = computed(() =>
5050
5151
const tagRows = computed(() => buildTaggedVersionRows(distTags.value))
5252
53+
const versionByKey = computed(() => new Map(versionHistory.value.map(v => [v.version, v])))
54+
5355
function getVersionTime(version: string): string | undefined {
54-
return versionHistory.value.find(v => v.version === version)?.time
56+
return versionByKey.value.get(version)?.time
5557
}
5658
5759
// ─── Version groups ───────────────────────────────────────────────────────────
@@ -86,7 +88,6 @@ function toggleGroup(groupKey: string) {
8688
} else {
8789
expandedGroups.value.add(groupKey)
8890
}
89-
expandedGroups.value = new Set(expandedGroups.value)
9091
}
9192
9293
// ─── Changelog side panel ─────────────────────────────────────────────────────
@@ -207,7 +208,7 @@ watch(jumpVersion, () => {
207208
<!-- Right: date + provenance -->
208209
<div class="flex flex-col items-end gap-1.5 shrink-0 relative z-10">
209210
<ProvenanceBadge
210-
v-if="versionHistory.find(v => v.version === tagRows?.[0]?.version)?.hasProvenance"
211+
v-if="versionByKey.get(tagRows[0].version)?.hasProvenance"
211212
:package-name="packageName"
212213
:version="tagRows[0].version"
213214
compact
@@ -265,7 +266,7 @@ watch(jumpVersion, () => {
265266

266267
<!-- Provenance -->
267268
<ProvenanceBadge
268-
v-if="versionHistory.find(v => v.version === row.version)?.hasProvenance"
269+
v-if="versionByKey.get(row.version)?.hasProvenance"
269270
:package-name="packageName"
270271
:version="row.version"
271272
compact
@@ -329,100 +330,91 @@ watch(jumpVersion, () => {
329330
</button>
330331

331332
<!-- Expanded versions -->
332-
<div
333-
class="grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none"
334-
:class="expandedGroups.has(group.groupKey) ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]'"
335-
>
336-
<div class="overflow-hidden border-t border-border">
333+
<div v-show="expandedGroups.has(group.groupKey)" class="border-t border-border">
334+
<div
335+
v-for="v in group.versions"
336+
:key="v.version"
337+
class="border-b border-border last:border-0 transition-colors"
338+
:class="selectedChangelogVersion === v.version ? 'bg-bg-subtle' : ''"
339+
>
337340
<div
338-
v-for="v in group.versions"
339-
:key="v.version"
340-
class="border-b border-border last:border-0 transition-colors"
341-
:class="selectedChangelogVersion === v.version ? 'bg-bg-subtle' : ''"
341+
class="flex items-center gap-3 px-4 ps-11 py-2.5 group relative"
342+
:class="selectedChangelogVersion === v.version ? '' : 'hover:bg-bg-subtle'"
342343
>
343-
<div
344-
class="flex items-center gap-3 px-4 ps-11 py-2.5 group relative"
345-
:class="selectedChangelogVersion === v.version ? '' : 'hover:bg-bg-subtle'"
346-
>
347-
<!-- Version + badges -->
348-
<div class="flex-1 min-w-0 flex items-center gap-2 flex-wrap">
349-
<LinkBase
350-
:to="packageRoute(packageName, v.version)"
351-
class="font-mono text-sm after:absolute after:inset-0 after:content-['']"
352-
:class="v.deprecated ? 'text-red-700 dark:text-red-400' : ''"
353-
:classicon="v.deprecated ? 'i-lucide:octagon-alert' : undefined"
354-
dir="ltr"
355-
>
356-
{{ v.version }}
357-
</LinkBase>
358-
<div
359-
v-if="v.tags?.length"
360-
class="flex items-center gap-1 flex-wrap relative z-10"
361-
>
362-
<span
363-
v-for="tag in v.tags"
364-
:key="tag"
365-
class="text-4xs font-semibold uppercase tracking-wide"
366-
:class="tag === 'latest' ? 'text-accent' : 'text-fg-subtle'"
367-
>
368-
{{ tag }}
369-
</span>
370-
</div>
344+
<!-- Version + badges -->
345+
<div class="flex-1 min-w-0 flex items-center gap-2 flex-wrap">
346+
<LinkBase
347+
:to="packageRoute(packageName, v.version)"
348+
class="font-mono text-sm after:absolute after:inset-0 after:content-['']"
349+
:class="v.deprecated ? 'text-red-700 dark:text-red-400' : ''"
350+
:classicon="v.deprecated ? 'i-lucide:octagon-alert' : undefined"
351+
dir="ltr"
352+
>
353+
{{ v.version }}
354+
</LinkBase>
355+
<div
356+
v-if="v.tags?.length"
357+
class="flex items-center gap-1 flex-wrap relative z-10"
358+
>
371359
<span
372-
v-if="v.deprecated"
373-
class="text-3xs font-medium text-red-700 dark:text-red-400 bg-red-100 dark:bg-red-900/30 px-1.5 py-0.5 rounded relative z-10"
374-
:title="v.deprecated"
360+
v-for="tag in v.tags"
361+
:key="tag"
362+
class="text-4xs font-semibold uppercase tracking-wide"
363+
:class="tag === 'latest' ? 'text-accent' : 'text-fg-subtle'"
375364
>
376-
deprecated
365+
{{ tag }}
377366
</span>
378367
</div>
368+
<span
369+
v-if="v.deprecated"
370+
class="text-3xs font-medium text-red-700 dark:text-red-400 bg-red-100 dark:bg-red-900/30 px-1.5 py-0.5 rounded relative z-10"
371+
:title="v.deprecated"
372+
>
373+
deprecated
374+
</span>
375+
</div>
379376

380-
<!-- Right side -->
381-
<div class="flex items-center gap-2 shrink-0 relative z-10">
382-
<!-- TODO(atriiy): changelog would be implemented later -->
383-
384-
<!-- Divider -->
385-
<span
386-
v-if="v.hasChangelog"
387-
class="w-px h-3.5 bg-border shrink-0 hidden sm:block"
388-
aria-hidden="true"
389-
/>
390-
391-
<!-- Metadata: date + provenance -->
392-
<DateTime
393-
v-if="v.time"
394-
:datetime="v.time"
395-
class="text-xs text-fg-subtle hidden sm:block"
396-
year="numeric"
397-
month="short"
398-
day="numeric"
399-
/>
400-
<ProvenanceBadge
401-
v-if="v.hasProvenance"
402-
:package-name="packageName"
403-
:version="v.version"
404-
compact
405-
:linked="false"
406-
/>
407-
</div>
377+
<!-- Right side -->
378+
<div class="flex items-center gap-2 shrink-0 relative z-10">
379+
<!-- TODO(atriiy): changelog would be implemented later -->
380+
381+
<!-- Divider -->
382+
<span
383+
v-if="v.hasChangelog"
384+
class="w-px h-3.5 bg-border shrink-0 hidden sm:block"
385+
aria-hidden="true"
386+
/>
387+
388+
<!-- Metadata: date + provenance -->
389+
<DateTime
390+
v-if="v.time"
391+
:datetime="v.time"
392+
class="text-xs text-fg-subtle hidden sm:block"
393+
year="numeric"
394+
month="short"
395+
day="numeric"
396+
/>
397+
<ProvenanceBadge
398+
v-if="v.hasProvenance"
399+
:package-name="packageName"
400+
:version="v.version"
401+
compact
402+
:linked="false"
403+
/>
408404
</div>
405+
</div>
409406

410-
<!-- Mobile inline changelog (below the row, sm and up uses side panel) -->
411-
<div
412-
v-if="v.hasChangelog"
413-
class="grid sm:hidden transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none"
414-
:class="
415-
selectedChangelogVersion === v.version
416-
? 'grid-rows-[1fr]'
417-
: 'grid-rows-[0fr]'
418-
"
419-
>
420-
<div class="overflow-hidden">
421-
<div class="changelog-body border-t border-border px-4 py-3 text-sm">
422-
{{
423-
selectedChangelogVersion === v.version ? selectedChangelogContent : ''
424-
}}
425-
</div>
407+
<!-- Mobile inline changelog (below the row, sm and up uses side panel) -->
408+
<div
409+
v-if="v.hasChangelog"
410+
class="grid sm:hidden transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none"
411+
:class="
412+
selectedChangelogVersion === v.version ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]'
413+
"
414+
>
415+
<div class="overflow-hidden">
416+
<div class="changelog-body border-t border-border px-4 py-3 text-sm">
417+
{{ selectedChangelogVersion === v.version ? selectedChangelogContent : '' }}
426418
</div>
427419
</div>
428420
</div>

0 commit comments

Comments
 (0)