Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [5.11.4](https://github.com/SocketDev/socket-lib/releases/tag/v5.11.4) - 2026-03-28

### Changed

- **perf**: Lazy-load heavy external sub-bundles across 7 modules (#119)
- `sorts.ts`: Defer semver (2.5 MB via npm-pack) and fastSort until first use
- `versions.ts`: Defer semver until first use
- `archives.ts`: Defer adm-zip (102 KB) and tar-fs (105 KB) until extraction
- `globs.ts`: Defer fast-glob and picomatch (260 KB via pico-pack) until glob execution
- `fs.ts`: Defer del (260 KB via pico-pack) until safeDelete call
- `spawn.ts`: Defer @npmcli/promise-spawn (17 KB) until async spawn
- `strings.ts`: Defer get-east-asian-width (10 KB) until stringWidth call
- Importing lightweight exports (isObject, httpJson, localeCompare, readJsonSync, stripAnsi) no longer loads heavy externals at module init time

## [5.11.3](https://github.com/SocketDev/socket-lib/releases/tag/v5.11.3) - 2026-03-26

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@socketsecurity/lib",
"version": "5.11.3",
"version": "5.11.4",
"packageManager": "pnpm@10.33.0",
"license": "MIT",
"description": "Core utilities and infrastructure for Socket.dev security tools",
Expand Down
33 changes: 16 additions & 17 deletions test/unit/cache-with-ttl.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -185,17 +185,17 @@ describe.sequential('cache-with-ttl', () => {
})

it('should fetch again after cache expires', async () => {
// Use longer TTL (200ms) to avoid flaky failures on slow CI runners.
// Use generous TTL to avoid flaky failures on slow CI runners (especially Windows).
const shortCache = createTtlCache({
ttl: 200,
ttl: 500,
prefix: 'short-cache',
})
const fetcher = vi.fn(async () => 'value')
await shortCache.getOrFetch('key', fetcher)
expect(fetcher).toHaveBeenCalledTimes(1)

// Wait for TTL to expire (300ms > 200ms TTL).
await new Promise(resolve => setTimeout(resolve, 300))
// Wait for TTL to expire (700ms > 500ms TTL).
await new Promise(resolve => setTimeout(resolve, 700))

await shortCache.getOrFetch('key', fetcher)
expect(fetcher).toHaveBeenCalledTimes(2)
Expand Down Expand Up @@ -327,17 +327,17 @@ describe.sequential('cache-with-ttl', () => {
})

it('should skip expired entries in getAll', async () => {
// Use longer TTL (200ms) to avoid flaky failures on slow CI runners.
// Use generous TTL to avoid flaky failures on slow CI runners (especially Windows).
const shortCache = createTtlCache({
ttl: 200,
ttl: 500,
prefix: 'expiry-getall-test',
})

await shortCache.set('key1', 'value1')
await shortCache.set('key2', 'value2')

// Wait for TTL to expire (300ms > 200ms TTL).
await new Promise(resolve => setTimeout(resolve, 300))
// Wait for TTL to expire (700ms > 500ms TTL).
await new Promise(resolve => setTimeout(resolve, 700))

const all = await shortCache.getAll<string>('*')
expect(all.size).toBe(0)
Expand Down Expand Up @@ -416,18 +416,17 @@ describe.sequential('cache-with-ttl', () => {

describe('TTL expiration', () => {
it('should expire entries after TTL', async () => {
// Use longer TTL (200ms) to avoid flaky failures on slow CI runners.
// Windows in particular can have significant I/O latency during cacache.put().
// Use generous TTL to avoid flaky failures on slow CI runners (especially Windows).
const shortCache = createTtlCache({
ttl: 200,
ttl: 500,
prefix: 'expiry-test',
})

await shortCache.set('key', 'value')
expect(await shortCache.get<string>('key')).toBe('value')

// Wait for TTL to expire (300ms > 200ms TTL).
await new Promise(resolve => setTimeout(resolve, 300))
// Wait for TTL to expire (700ms > 500ms TTL).
await new Promise(resolve => setTimeout(resolve, 700))

expect(await shortCache.get('key')).toBeUndefined()

Expand All @@ -453,16 +452,16 @@ describe.sequential('cache-with-ttl', () => {

it('should refresh TTL on set', async () => {
const refreshCache = createTtlCache({
ttl: 300,
ttl: 2000,
prefix: 'refresh-cache',
})

await refreshCache.set('key', 'value1')
await new Promise(resolve => setTimeout(resolve, 100))
await new Promise(resolve => setTimeout(resolve, 200))
await refreshCache.set('key', 'value2') // Refresh TTL

await new Promise(resolve => setTimeout(resolve, 100))
// Should still be cached (100 + 100 = 200ms, but TTL refreshed at 100ms to 300ms)
await new Promise(resolve => setTimeout(resolve, 200))
// Should still be cached (200 + 200 = 400ms, but TTL refreshed at 200ms to 2000ms)
expect(await refreshCache.get<string>('key')).toBe('value2')

await refreshCache.clear()
Expand Down
Loading