forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1/**
2 * Result of install size calculation
3 */
4export interface InstallSizeResult {
5 /** Package name */
6 package: string
7 /** Package version */
8 version: string
9 /** Unpacked size of the package itself (bytes) */
10 selfSize: number
11 /** Total unpacked size including all dependencies (bytes) */
12 totalSize: number
13 /** Number of dependencies (including transitive) */
14 dependencyCount: number
15 /** Breakdown of dependency sizes */
16 dependencies: DependencySize[]
17}
18
19export interface DependencySize {
20 name: string
21 version: string
22 size: number
23 /** True if this is an optional dependency */
24 optional?: boolean
25}
26
27/**
28 * Calculate the total install size for a package.
29 *
30 * Resolves dependencies by fetching packuments directly from the npm registry.
31 * No filesystem operations - safe for serverless environments.
32 *
33 * Dependencies are resolved for linux-x64-glibc as a representative platform.
34 */
35export const calculateInstallSize = defineCachedFunction(
36 async (name: string, version: string): Promise<InstallSizeResult> => {
37 const resolved = await resolveDependencyTree(name, version)
38
39 // Separate self from dependencies
40 const selfKey = `${name}@${version}`
41 const selfEntry = resolved.get(selfKey)
42 const selfSize = selfEntry?.size ?? 0
43
44 // Build dependencies list (excluding self)
45 const dependencies: DependencySize[] = []
46 let totalSize = selfSize
47 let dependencyCount = 0
48
49 for (const [key, dep] of resolved) {
50 if (key === selfKey) continue
51
52 dependencies.push({
53 name: dep.name,
54 version: dep.version,
55 size: dep.size,
56 optional: dep.optional || undefined,
57 })
58 totalSize += dep.size
59 dependencyCount++
60 }
61
62 // Sort by size descending
63 dependencies.sort((a, b) => b.size - a.size)
64
65 return {
66 package: name,
67 version,
68 selfSize,
69 totalSize,
70 dependencyCount,
71 dependencies,
72 }
73 },
74 {
75 // Cache for 1 hour - dependency resolutions can change with new releases
76 maxAge: 60 * 60,
77 swr: true,
78 name: 'install-size',
79 getKey: (name: string, version: string) => `${name}@${version}`,
80 },
81)