Skip to content

Commit e83674f

Browse files
committed
perf(build): bundle all deps and stub heavy internals
Move @socketsecurity/lib and form-data from dependencies to devDependencies so esbuild bundles them into the dist output, making the SDK a zero-runtime-dependency package. Add esbuild stub plugin to replace heavy modules with minimal stubs: @socketsecurity/lib internals: - npm-pack.js (2.5MB): npm tooling (arborist, cacache, pacote, semver) — cacache usage degrades gracefully (safeGet returns undefined, in-memory memoization still works) - pico-pack.js (260KB): glob deps (picomatch, fast-glob, del) - globs.js, sorts.js: gateway modules to pico-pack and npm-pack Third-party: - mime-db (212KB): replaced with 3-entry lookup for the MIME types the SDK actually uses (application/json, application/octet-stream, multipart/form-data). Safe because the SDK always passes explicit contentType to form-data, so mime.lookup is never called. dist/index.js: 3,897KB → 712KB (82% reduction), zero dependencies.
1 parent 3905010 commit e83674f

4 files changed

Lines changed: 74 additions & 24 deletions

File tree

.config/esbuild.config.mjs

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,56 @@ function createNodeProtocolPlugin() {
206206
}
207207
}
208208

209+
/**
210+
* Plugin to stub heavy @socketsecurity/lib internals and third-party modules
211+
* that are unreachable or safely degradable in the SDK's runtime code paths.
212+
*
213+
* @socketsecurity/lib stubs:
214+
*
215+
* npm-pack.js (2.5MB) — arborist, cacache, pacote, make-fetch-happen,
216+
* semver. Reached via sorts→semver (dead) and cache-with-ttl→cacache
217+
* (degrades gracefully: safeGet returns undefined, in-memory memoization
218+
* still works).
219+
*
220+
* pico-pack.js (260KB) — picomatch, fast-glob, del. Reached via
221+
* fs→globs for isDirEmptySync/readDirNames, never called by SDK.
222+
*
223+
* globs.js, sorts.js — gateway modules to pico-pack and npm-pack.
224+
*
225+
* Third-party stubs:
226+
*
227+
* mime-db (212KB) — Massive MIME type database bundled via form-data →
228+
* mime-types → mime-db. The SDK only uses 'application/octet-stream'
229+
* (file uploads) and 'application/json' (API calls). Replaced with a
230+
* minimal lookup covering just those types.
231+
*/
232+
function createLibStubPlugin() {
233+
const libStubPattern =
234+
/@socketsecurity\/lib\/dist\/(globs|sorts|external\/(npm-pack|pico-pack))\.js$/
235+
236+
const mimeDbPattern = /mime-db\/db\.json$/
237+
238+
return {
239+
name: 'stub-unused-internals',
240+
setup(build) {
241+
// Stub heavy lib modules with empty exports.
242+
build.onLoad({ filter: libStubPattern }, () => ({
243+
contents: 'module.exports = {}',
244+
loader: 'js',
245+
}))
246+
// Replace 212KB mime-db with minimal lookup for types the SDK uses.
247+
build.onLoad({ filter: mimeDbPattern }, () => ({
248+
contents: `module.exports = {
249+
"application/json": { source: "iana", charset: "UTF-8", compressible: true },
250+
"application/octet-stream": { source: "iana", compressible: false },
251+
"multipart/form-data": { source: "iana" }
252+
}`,
253+
loader: 'js',
254+
}))
255+
},
256+
}
257+
}
258+
209259
// Build configuration for ESM output
210260
export const buildConfig = {
211261
entryPoints: [`${srcPath}/index.ts`, `${srcPath}/testing.ts`],
@@ -226,9 +276,11 @@ export const buildConfig = {
226276
logLevel: 'info',
227277

228278
// Use plugins for module resolution and path handling.
229-
plugins: [createNodeProtocolPlugin(), createPathShorteningPlugin()].filter(
230-
Boolean,
231-
),
279+
plugins: [
280+
createLibStubPlugin(),
281+
createNodeProtocolPlugin(),
282+
createPathShorteningPlugin(),
283+
].filter(Boolean),
232284

233285
// External dependencies.
234286
// All runtime dependencies from package.json are external (not bundled) - consumers must install them.

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
- Dependencies: After `package.json` edits, run `pnpm install` to update `pnpm-lock.yaml`
2222
- Backward Compatibility: 🚨 FORBIDDEN to maintain - actively remove when encountered (see canonical CLAUDE.md)
2323
- 🚨 **NEVER use `npx`, `pnpm dlx`, or `yarn dlx`** — use `pnpm exec <package>` for devDep binaries, or `pnpm run <script>` for package.json scripts. If a tool is needed, add it as a pinned devDependency first.
24+
- **minimumReleaseAge**: NEVER add packages to `minimumReleaseAgeExclude` in CI. Locally, ASK before adding — the age threshold is a security control.
2425

2526
---
2627

package.json

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,9 @@
6464
"type": "tsgo --noEmit -p .config/tsconfig.check.json",
6565
"update": "node scripts/update.mjs"
6666
},
67-
"dependencies": {
68-
"@socketsecurity/lib": "5.15.0",
69-
"form-data": "4.0.5"
70-
},
7167
"devDependencies": {
7268
"@anthropic-ai/claude-code": "2.1.92",
69+
"@socketsecurity/lib": "5.18.2",
7370
"@babel/generator": "7.28.5",
7471
"@babel/parser": "7.26.3",
7572
"@babel/traverse": "7.26.4",
@@ -87,6 +84,7 @@
8784
"ecc-agentshield": "1.4.0",
8885
"esbuild": "0.25.11",
8986
"fast-glob": "3.3.3",
87+
"form-data": "4.0.5",
9088
"husky": "9.1.7",
9189
"magic-string": "0.30.14",
9290
"nock": "14.0.10",
@@ -120,7 +118,7 @@
120118
"unrs-resolver"
121119
],
122120
"overrides": {
123-
"defu": ">=6.1.6",
121+
"defu": ">=6.1.7",
124122
"vite": "7.3.2"
125123
}
126124
}

pnpm-lock.yaml

Lines changed: 15 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)