Skip to content

Commit 11b88cb

Browse files
committed
perf: lazy-load semver and fastSort in sorts and versions modules
sorts.ts: Convert semver and fastSort to lazy require() calls via getSemver()/getFastSort() getters with hoisted local variables. Only loaded when compareSemver() or naturalSorter() is first called. versions.ts: Convert semver to lazy require() via getSemver() getter. Every function delegates to the getter on first call. Impact: importing @socketsecurity/lib/objects (for isObject) or @socketsecurity/lib/http-request (for httpJson) no longer transitively loads the 2.5 MB npm-pack bundle at module init time via the sorts -> semver -> npm-pack chain.
1 parent ab2e353 commit 11b88cb

2 files changed

Lines changed: 52 additions & 27 deletions

File tree

src/sorts.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,34 @@
33
* Provides various comparison utilities for arrays and collections.
44
*/
55

6-
import * as fastSort from './external/fast-sort.js'
7-
import * as semver from './external/semver.js'
6+
import type * as fastSortType from './external/fast-sort.js'
7+
import type * as semverType from './external/semver.js'
8+
9+
let _semver: typeof semverType | undefined
10+
function getSemver() {
11+
if (_semver === undefined) {
12+
_semver = require('./external/semver.js')
13+
}
14+
return _semver!
15+
}
16+
17+
let _fastSort: typeof fastSortType | undefined
18+
function getFastSort() {
19+
if (_fastSort === undefined) {
20+
_fastSort = require('./external/fast-sort.js')
21+
}
22+
return _fastSort!
23+
}
824

925
/**
1026
* Compare semantic versions.
1127
*/
1228
/*@__NO_SIDE_EFFECTS__*/
1329
export function compareSemver(a: string, b: string): number {
1430
/* c8 ignore next 2 - External semver calls */
15-
const validA: string | null = semver.valid(a)
16-
const validB: string | null = semver.valid(b)
31+
const sv = getSemver()
32+
const validA: string | null = sv.valid(a)
33+
const validB: string | null = sv.valid(b)
1734

1835
if (!validA && !validB) {
1936
return 0
@@ -25,7 +42,7 @@ export function compareSemver(a: string, b: string): number {
2542
return 1
2643
}
2744
/* c8 ignore next - External semver call */
28-
return semver.compare(a, b) as number
45+
return sv.compare(a, b) as number
2946
}
3047

3148
/**
@@ -90,7 +107,7 @@ export function naturalSorter<T>(
90107
): ReturnType<FastSortFunction> {
91108
if (_naturalSorter === undefined) {
92109
/* c8 ignore next 3 - External fast-sort call */
93-
_naturalSorter = fastSort.createNewSortInstance({
110+
_naturalSorter = getFastSort().createNewSortInstance({
94111
comparer: naturalCompare,
95112
}) as FastSortFunction
96113
}

src/versions.ts

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
/** @fileoverview Version comparison and validation utilities for Socket ecosystem. */
22

3-
import * as semver from './external/semver.js'
3+
import type * as semverType from './external/semver.js'
4+
5+
let _semver: typeof semverType | undefined
6+
function getSemver() {
7+
if (_semver === undefined) {
8+
_semver = require('./external/semver.js')
9+
}
10+
return _semver!
11+
}
412

513
/**
614
* Coerce a version string to valid semver format.
715
*/
816
export function coerceVersion(version: string): string | undefined {
917
/* c8 ignore next - External semver call */
10-
const coerced = semver.coerce(version)
18+
const coerced = getSemver().coerce(version)
1119
return coerced?.version
1220
}
1321

@@ -21,7 +29,7 @@ export function compareVersions(
2129
): -1 | 0 | 1 | undefined {
2230
try {
2331
/* c8 ignore next - External semver call */
24-
return semver.compare(v1, v2)
32+
return getSemver().compare(v1, v2)
2533
} catch {
2634
return undefined
2735
}
@@ -32,15 +40,15 @@ export function compareVersions(
3240
*/
3341
export function filterVersions(versions: string[], range: string): string[] {
3442
/* c8 ignore next - External semver call */
35-
return versions.filter(v => semver.satisfies(v, range))
43+
return versions.filter(v => getSemver().satisfies(v, range))
3644
}
3745

3846
/**
3947
* Get the major version number from a version string.
4048
*/
4149
export function getMajorVersion(version: string): number | undefined {
4250
/* c8 ignore next - External semver call */
43-
const parsed = semver.parse(version)
51+
const parsed = getSemver().parse(version)
4452
return parsed?.major
4553
}
4654

@@ -49,7 +57,7 @@ export function getMajorVersion(version: string): number | undefined {
4957
*/
5058
export function getMinorVersion(version: string): number | undefined {
5159
/* c8 ignore next - External semver call */
52-
const parsed = semver.parse(version)
60+
const parsed = getSemver().parse(version)
5361
return parsed?.minor
5462
}
5563

@@ -58,7 +66,7 @@ export function getMinorVersion(version: string): number | undefined {
5866
*/
5967
export function getPatchVersion(version: string): number | undefined {
6068
/* c8 ignore next - External semver call */
61-
const parsed = semver.parse(version)
69+
const parsed = getSemver().parse(version)
6270
return parsed?.patch
6371
}
6472

@@ -78,23 +86,23 @@ export function incrementVersion(
7886
identifier?: string | undefined,
7987
): string | undefined {
8088
/* c8 ignore next - External semver call */
81-
return semver.inc(version, release, identifier) || undefined
89+
return getSemver().inc(version, release, identifier) || undefined
8290
}
8391

8492
/**
8593
* Check if version1 equals version2.
8694
*/
8795
export function isEqual(version1: string, version2: string): boolean {
8896
/* c8 ignore next - External semver call */
89-
return semver.eq(version1, version2)
97+
return getSemver().eq(version1, version2)
9098
}
9199

92100
/**
93101
* Check if version1 is greater than version2.
94102
*/
95103
export function isGreaterThan(version1: string, version2: string): boolean {
96104
/* c8 ignore next - External semver call */
97-
return semver.gt(version1, version2)
105+
return getSemver().gt(version1, version2)
98106
}
99107

100108
/**
@@ -105,47 +113,47 @@ export function isGreaterThanOrEqual(
105113
version2: string,
106114
): boolean {
107115
/* c8 ignore next - External semver call */
108-
return semver.gte(version1, version2)
116+
return getSemver().gte(version1, version2)
109117
}
110118

111119
/**
112120
* Check if version1 is less than version2.
113121
*/
114122
export function isLessThan(version1: string, version2: string): boolean {
115123
/* c8 ignore next - External semver call */
116-
return semver.lt(version1, version2)
124+
return getSemver().lt(version1, version2)
117125
}
118126

119127
/**
120128
* Check if version1 is less than or equal to version2.
121129
*/
122130
export function isLessThanOrEqual(version1: string, version2: string): boolean {
123131
/* c8 ignore next - External semver call */
124-
return semver.lte(version1, version2)
132+
return getSemver().lte(version1, version2)
125133
}
126134

127135
/**
128136
* Validate if a string is a valid semantic version.
129137
*/
130138
export function isValidVersion(version: string): boolean {
131139
/* c8 ignore next - External semver call */
132-
return semver.valid(version) !== null
140+
return getSemver().valid(version) !== null
133141
}
134142

135143
/**
136144
* Get the highest version from an array of versions.
137145
*/
138146
export function maxVersion(versions: string[]): string | undefined {
139147
/* c8 ignore next - External semver call */
140-
return semver.maxSatisfying(versions, '*') || undefined
148+
return getSemver().maxSatisfying(versions, '*') || undefined
141149
}
142150

143151
/**
144152
* Get the lowest version from an array of versions.
145153
*/
146154
export function minVersion(versions: string[]): string | undefined {
147155
/* c8 ignore next - External semver call */
148-
return semver.minSatisfying(versions, '*') || undefined
156+
return getSemver().minSatisfying(versions, '*') || undefined
149157
}
150158

151159
/**
@@ -161,7 +169,7 @@ export function parseVersion(version: string):
161169
}
162170
| undefined {
163171
/* c8 ignore next - External semver call */
164-
const parsed = semver.parse(version)
172+
const parsed = getSemver().parse(version)
165173
if (!parsed) {
166174
return undefined
167175
}
@@ -179,23 +187,23 @@ export function parseVersion(version: string):
179187
*/
180188
export function satisfiesVersion(version: string, range: string): boolean {
181189
/* c8 ignore next - External semver call */
182-
return semver.satisfies(version, range)
190+
return getSemver().satisfies(version, range)
183191
}
184192

185193
/**
186194
* Sort versions in ascending order.
187195
*/
188196
export function sortVersions(versions: string[]): string[] {
189197
/* c8 ignore next - External semver call */
190-
return semver.sort([...versions])
198+
return getSemver().sort([...versions])
191199
}
192200

193201
/**
194202
* Sort versions in descending order.
195203
*/
196204
export function sortVersionsDesc(versions: string[]): string[] {
197205
/* c8 ignore next - External semver call */
198-
return semver.rsort([...versions])
206+
return getSemver().rsort([...versions])
199207
}
200208

201209
/**
@@ -216,7 +224,7 @@ export function versionDiff(
216224
| undefined {
217225
try {
218226
/* c8 ignore next - External semver call */
219-
return semver.diff(version1, version2) || undefined
227+
return getSemver().diff(version1, version2) || undefined
220228
} catch {
221229
return undefined
222230
}

0 commit comments

Comments
 (0)