Skip to content

Conversation

@berenddeboer
Copy link
Contributor

@berenddeboer berenddeboer commented Nov 26, 2025

Key optimisations:

  1. Pre-computed PackageIndex - Built once during lockfile parsing:
    • byName: Map from package name → array of versions (O(1) lookup)
    • workspaceNames: Set of workspace package names (O(1) lookup)
    • workspacePaths: Set of workspace paths (O(1) lookup)
    • packagesWithWorkspaceVariants: Set of packages with workspace-specific variants (O(1) lookup)
    • patchedPackages: Set of patched package names (O(1) lookup)
  2. findResolvedVersion: Changed from O(n) scan through all packages to O(1) map lookup + O(k) where k = number of versions for that package (typically 1-3)
  3. isWorkspacePackage: Changed from O(n) scan to O(1) set lookup
  4. hasWorkspaceSpecificVariant: Changed from O(n) scan to O(1) set lookup
  5. isNestedPackageKey: Now uses pre-computed workspace paths/names sets instead of computing them each call

On my 40 project typescript monorepo my time goes from about 30 seconds to 4.5s, a speed-up of 6-7x.

Key Optimizations Made

1. Pre-computed PackageIndex - Built once during lockfile parsing:
   - byName: Map from package name → array of versions (O(1) lookup)
   - workspaceNames: Set of workspace package names (O(1) lookup)
   - workspacePaths: Set of workspace paths (O(1) lookup)
   - packagesWithWorkspaceVariants: Set of packages with workspace-specific variants
(O(1) lookup)
   - patchedPackages: Set of patched package names (O(1) lookup)

2. findResolvedVersion: Changed from O(n) scan through all packages to O(1) map
lookup + O(k) where k = number of versions for that package (typically 1-3)

3. isWorkspacePackage: Changed from O(n) scan to O(1) set lookup

4. hasWorkspaceSpecificVariant: Changed from O(n) scan to O(1) set lookup

5. isNestedPackageKey: Now uses pre-computed workspace paths/names sets instead of
computing them each call
@berenddeboer berenddeboer requested review from a team and meeroslav as code owners November 26, 2025 05:26
@netlify
Copy link

netlify bot commented Nov 26, 2025

👷 Deploy request for nx-docs pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit e2246c4

@vercel
Copy link

vercel bot commented Nov 26, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
nx-dev Ready Ready Preview Nov 26, 2025 5:50am

@berenddeboer berenddeboer changed the title fix(nx): optimize bun lockfile parser with O(1) lookups fix(nx): optimize bun lockfile parser with O(1) lookups: 7x better Nov 26, 2025
const prefix = packageKey.substring(0, lastSlash);

// If the prefix is a workspace path or scoped package pattern
if (workspacePaths.has(prefix) || prefix.startsWith('@')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing condition in workspace variant detection. The old logic checked prefix.startsWith('@') && prefix.includes('/') but the new code only checks prefix.startsWith('@'). This could incorrectly identify packages as workspace-specific variants.

For example, if a package key is split where the prefix is just @scope (without a slash), it would incorrectly match, whereas the old code would reject it.

Fix:

if (workspacePaths.has(prefix) || (prefix.startsWith('@') && prefix.includes('/'))) {
  packagesWithWorkspaceVariants.add(possiblePackageName);
}
Suggested change
if (workspacePaths.has(prefix) || prefix.startsWith('@')) {
if (workspacePaths.has(prefix) || (prefix.startsWith('@') && prefix.includes('/'))) {

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

We fixed two related bugs in the workspace variant detection logic:

Bug 1: buildPackageIndex - Missing condition in workspace variant detection

Location: packages/nx/src/plugins/js/lock-file/bun-parser.ts:492

Problem: The check prefix.startsWith('@') was missing the additional condition
prefix.includes('/'). This could incorrectly identify packages as workspace-specific
variants when the prefix is just @scope (without a slash).

Bug 2: isNestedPackageKey - Scoped packages incorrectly filtered as nested

Location: packages/nx/src/plugins/js/lock-file/bun-parser.ts:1200-1205

Problem: The function's final return true would incorrectly filter legitimate scoped
packages like @types/react or scoped aliases like @custom/lodash as nested packages.

Fix: Added a check before the final return true to recognize simple scoped packages
(2-part keys starting with @).
@berenddeboer berenddeboer changed the title fix(nx): optimize bun lockfile parser with O(1) lookups: 7x better fix(nx): optimize bun lockfile parser with O(1) lookups: 7x faster Nov 27, 2025
@yharaskrik
Copy link
Contributor

🥺

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants