[READ-ONLY] a fast, modern browser for the npm registry
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf: slim down packument in payload

+94
+68
app/composables/useNpmRegistry.ts
··· 1 1 import type { 2 2 Packument, 3 + PackumentVersion, 4 + SlimPackument, 3 5 NpmSearchResponse, 4 6 NpmDownloadCount, 5 7 NpmDownloadRange, ··· 66 68 return encodeURIComponent(name) 67 69 } 68 70 71 + /** Maximum number of versions to include in the client payload */ 72 + const MAX_VERSIONS = 20 73 + 74 + /** 75 + * Transform a full Packument into a slimmed version for client-side use. 76 + * Reduces payload size by: 77 + * - Removing readme (fetched separately) 78 + * - Limiting versions to recent MAX_VERSIONS 79 + * - Stripping unnecessary fields from version objects 80 + */ 81 + function transformPackument(pkg: Packument): SlimPackument { 82 + // Sort versions by publish time (newest first) 83 + const sortedVersionKeys = Object.keys(pkg.versions) 84 + .filter(v => pkg.time[v]) // Only versions with timestamps 85 + .sort((a, b) => { 86 + const timeA = pkg.time[a] 87 + const timeB = pkg.time[b] 88 + if (!timeA || !timeB) return 0 89 + return new Date(timeB).getTime() - new Date(timeA).getTime() 90 + }) 91 + .slice(0, MAX_VERSIONS) 92 + 93 + // Always include the latest dist-tag version even if not in top MAX_VERSIONS 94 + const latestTag = pkg['dist-tags']?.latest 95 + if (latestTag && !sortedVersionKeys.includes(latestTag)) { 96 + sortedVersionKeys.push(latestTag) 97 + } 98 + 99 + // Build filtered versions object 100 + const filteredVersions: Record<string, PackumentVersion> = {} 101 + for (const v of sortedVersionKeys) { 102 + const version = pkg.versions[v] 103 + if (version) { 104 + // Strip readme and scripts from each version to reduce size 105 + const { readme: _readme, scripts: _scripts, ...slimVersion } = version 106 + filteredVersions[v] = slimVersion as PackumentVersion 107 + } 108 + } 109 + 110 + // Build filtered time object (only for included versions) 111 + const filteredTime: Record<string, string> = {} 112 + if (pkg.time.modified) filteredTime.modified = pkg.time.modified 113 + if (pkg.time.created) filteredTime.created = pkg.time.created 114 + for (const v of sortedVersionKeys) { 115 + if (pkg.time[v]) filteredTime[v] = pkg.time[v] 116 + } 117 + 118 + return { 119 + '_id': pkg._id, 120 + '_rev': pkg._rev, 121 + 'name': pkg.name, 122 + 'description': pkg.description, 123 + 'dist-tags': pkg['dist-tags'], 124 + 'time': filteredTime, 125 + 'maintainers': pkg.maintainers, 126 + 'author': pkg.author, 127 + 'license': pkg.license, 128 + 'homepage': pkg.homepage, 129 + 'keywords': pkg.keywords, 130 + 'repository': pkg.repository, 131 + 'bugs': pkg.bugs, 132 + 'versions': filteredVersions, 133 + } 134 + } 135 + 69 136 export function usePackage(name: MaybeRefOrGetter<string>) { 70 137 const registry = useNpmRegistry() 71 138 72 139 return useLazyAsyncData( 73 140 () => `package:${toValue(name)}`, 74 141 () => registry.fetchPackage(toValue(name)), 142 + { transform: transformPackument }, 75 143 ) 76 144 } 77 145
+26
shared/types/npm-registry.ts
··· 10 10 export type { Packument, PackumentVersion, Manifest, ManifestVersion, PackageJSON } from '@npm/types' 11 11 12 12 /** 13 + * Slimmed down Packument for client-side use. 14 + * Strips unnecessary fields to reduce payload size. 15 + * - readme removed (fetched separately) 16 + * - versions limited to recent 20 17 + * - time limited to recent 20 versions 18 + */ 19 + export interface SlimPackument { 20 + '_id': string 21 + '_rev'?: string 22 + 'name': string 23 + 'description'?: string 24 + 'dist-tags': { latest?: string } & Record<string, string> 25 + /** Only includes time for recent versions + modified/created */ 26 + 'time': { modified?: string, created?: string } & Record<string, string> 27 + 'maintainers'?: NpmPerson[] 28 + 'author'?: NpmPerson 29 + 'license'?: string 30 + 'homepage'?: string 31 + 'keywords'?: string[] 32 + 'repository'?: { type?: string, url?: string, directory?: string } 33 + 'bugs'?: { url?: string, email?: string } 34 + /** Only includes recent 20 versions */ 35 + 'versions': Record<string, import('@npm/types').PackumentVersion> 36 + } 37 + 38 + /** 13 39 * Person/contact type extracted from @npm/types Contact interface 14 40 * Used for maintainers, authors, publishers 15 41 */