Skip to content

Commit 21b807b

Browse files
committed
perf(npm): convert name lookups from Array.includes to Set.has
isNpmLegacyName and isNpmBuiltinName now use lazily-initialized Sets for O(1) lookups instead of O(n) array scans. These functions are called twice per npm PURL parse (normalize + validate).
1 parent b5d19f1 commit 21b807b

1 file changed

Lines changed: 17 additions & 14 deletions

File tree

src/purl-types/npm.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,13 @@ export type NpmPackageComponents = {
6060
}
6161

6262
/**
63-
* Get list of Node.js built-in module names.
63+
* Get Set of Node.js built-in module names for O(1) lookups.
6464
*/
65-
const getNpmBuiltinNames = (() => {
66-
let builtinNames: string[] | undefined
65+
const getNpmBuiltinSet = (() => {
66+
let builtinSet: Set<string> | undefined
6767
return () => {
68-
if (builtinNames === undefined) {
68+
if (builtinSet === undefined) {
69+
let builtinNames: string[] | undefined
6970
/* c8 ignore start - Error handling for module access. */
7071
try {
7172
// Try to use Node.js builtinModules first
@@ -120,8 +121,9 @@ const getNpmBuiltinNames = (() => {
120121
'zlib',
121122
]
122123
}
124+
builtinSet = new Set(builtinNames)
123125
}
124-
return builtinNames
126+
return builtinSet
125127
}
126128
})()
127129

@@ -134,13 +136,14 @@ function getNpmId(purl: PurlObject): string {
134136
}
135137

136138
/**
137-
* Get list of npm legacy package names.
139+
* Get Set of npm legacy package names for O(1) lookups.
138140
*/
139-
const getNpmLegacyNames = (() => {
140-
let fullLegacyNames: string[] | undefined
141+
const getNpmLegacySet = (() => {
142+
let legacySet: Set<string> | undefined
141143

142-
return (): string[] => {
143-
if (fullLegacyNames === undefined) {
144+
return (): Set<string> => {
145+
if (legacySet === undefined) {
146+
let fullLegacyNames: string[]
144147
/* c8 ignore start - Fallback path only used if JSON file fails to load. */
145148
try {
146149
// Try to load the full list from JSON file
@@ -161,22 +164,22 @@ const getNpmLegacyNames = (() => {
161164
]
162165
}
163166
/* c8 ignore stop */
167+
legacySet = new Set(fullLegacyNames)
164168
}
165-
return fullLegacyNames!
169+
return legacySet
166170
}
167171
})()
168172

169173
/**
170174
* Check if npm identifier is a Node.js built-in module name.
171175
*/
172176
const isNpmBuiltinName = (id: string): boolean =>
173-
getNpmBuiltinNames().includes(id.toLowerCase())
177+
getNpmBuiltinSet().has(id.toLowerCase())
174178

175179
/**
176180
* Check if npm identifier is a legacy package name.
177181
*/
178-
const isNpmLegacyName = (id: string): boolean =>
179-
getNpmLegacyNames().includes(id)
182+
const isNpmLegacyName = (id: string): boolean => getNpmLegacySet().has(id)
180183

181184
/**
182185
* Normalize npm package URL.

0 commit comments

Comments
 (0)