diff --git a/.changeset/kind-radios-admire.md b/.changeset/kind-radios-admire.md new file mode 100644 index 0000000000..3e99b37eb5 --- /dev/null +++ b/.changeset/kind-radios-admire.md @@ -0,0 +1,6 @@ +--- +"@pnpm/resolve-dependencies": patch +"pnpm": patch +--- + +Improve the performance of the peers resolution stage by utilizing more cache [#8058](https://github.com/pnpm/pnpm/pull/8058). diff --git a/pkg-manager/resolve-dependencies/src/resolvePeers.ts b/pkg-manager/resolve-dependencies/src/resolvePeers.ts index d65822d402..774062b45f 100644 --- a/pkg-manager/resolve-dependencies/src/resolvePeers.ts +++ b/pkg-manager/resolve-dependencies/src/resolvePeers.ts @@ -350,28 +350,40 @@ async function resolvePeersOfNode ( })) ) ) - const hit = ctx.peersCache.get(resolvedPackage.depPath)?.find((cache) => { - for (const [name, cachedNodeId] of cache.resolvedPeers) { - const parentPkgNodeId = parentPkgs[name]?.nodeId - if (!parentPkgNodeId || !cachedNodeId) return false - if (parentPkgNodeId === cachedNodeId) continue - if ( - ctx.pathsByNodeId.has(cachedNodeId) && - ctx.pathsByNodeId.get(cachedNodeId) === ctx.pathsByNodeId.get(parentPkgNodeId) - ) continue - if (!ctx.dependenciesTree.has(parentPkgNodeId) && parentPkgNodeId.startsWith('link:')) { - return false + const hit = findHit(resolvedPackage.depPath) + function findHit (depPath: string, pendingCacheSearches: string[] = []) { + const cacheItems = ctx.peersCache.get(depPath) + if (!cacheItems) return undefined + const newPendingCacheSearches = [...pendingCacheSearches, depPath] + return cacheItems.find((cache) => { + for (const [name, cachedNodeId] of cache.resolvedPeers) { + const parentPkgNodeId = parentPkgs[name]?.nodeId + if (!parentPkgNodeId || !cachedNodeId) return false + if (parentPkgNodeId === cachedNodeId) continue + if ( + ctx.pathsByNodeId.has(cachedNodeId) && + ctx.pathsByNodeId.get(cachedNodeId) === ctx.pathsByNodeId.get(parentPkgNodeId) + ) continue + if (!ctx.dependenciesTree.has(parentPkgNodeId) && parentPkgNodeId.startsWith('link:')) { + return false + } + const parentDepPath = (ctx.dependenciesTree.get(parentPkgNodeId)!.resolvedPackage as T).depPath + if (!ctx.purePkgs.has(parentDepPath)) { + if ( + newPendingCacheSearches.includes(parentDepPath) || + findHit(parentDepPath, newPendingCacheSearches) + ) continue + return false + } + const cachedDepPath = (ctx.dependenciesTree.get(cachedNodeId)!.resolvedPackage as T).depPath + if (parentDepPath !== cachedDepPath) return false } - const parentDepPath = (ctx.dependenciesTree.get(parentPkgNodeId)!.resolvedPackage as T).depPath - if (!ctx.purePkgs.has(parentDepPath)) return false - const cachedDepPath = (ctx.dependenciesTree.get(cachedNodeId)!.resolvedPackage as T).depPath - if (parentDepPath !== cachedDepPath) return false - } - for (const missingPeer of cache.missingPeers) { - if (parentPkgs[missingPeer]) return false - } - return true - }) + for (const missingPeer of cache.missingPeers) { + if (parentPkgs[missingPeer]) return false + } + return true + }) + } if (hit != null) { return { missingPeers: hit.missingPeers,