Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: use hash to replace createHash #8629

Merged
merged 7 commits into from
Oct 21, 2024
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
5 changes: 5 additions & 0 deletions .changeset/lemon-sheep-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@pnpm/crypto.polyfill": major
---

Initial release.
10 changes: 10 additions & 0 deletions .changeset/quiet-carrots-march.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@pnpm/npm-resolver": patch
"@pnpm/core": patch
"@pnpm/crypto.polyfill": patch
"@pnpm/list": patch
"@pnpm/worker": patch
"pnpm": patch
---

Use `crypto.hash`, when available, for improved performance [#8629](https://github.com/pnpm/pnpm/pull/8629).
15 changes: 15 additions & 0 deletions crypto/polyfill/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# @pnpm/crypto.polyfill

> Polyfill for functions in the crypto library

[![npm version](https://img.shields.io/npm/v/@pnpm/crypto.polyfill.svg)](https://www.npmjs.com/package/@pnpm/crypto.polyfill)

## Installation

```sh
pnpm add @pnpm/crypto.polyfill
```

## License

MIT
38 changes: 38 additions & 0 deletions crypto/polyfill/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@pnpm/crypto.polyfill",
"version": "0.0.0",
"description": "Polyfill for functions in the crypto library",
"funding": "https://opencollective.com/pnpm",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib",
"!*.map"
],
"exports": {
".": "./lib/index.js"
},
"engines": {
"node": ">=18.12"
},
"scripts": {
"lint": "eslint \"src/**/*.ts\"",
"test": "pnpm run compile",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"
},
"repository": "https://github.com/pnpm/pnpm/blob/main/crypto/polyfill",
"keywords": [
"pnpm9",
"pnpm",
"crypto"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/pnpm/pnpm/issues"
},
"homepage": "https://github.com/pnpm/pnpm/blob/main/crypto/polyfill#readme",
"devDependencies": {
"@pnpm/crypto.polyfill": "workspace:*"
}
}
10 changes: 10 additions & 0 deletions crypto/polyfill/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import crypto from 'crypto'

export const hash =
// @ts-expect-error -- crypto.hash is supported in Node 21.7.0+, 20.12.0+
crypto.hash ??
((
algorithm: string,
data: crypto.BinaryLike,
outputEncoding: crypto.BinaryToTextEncoding
) => crypto.createHash(algorithm).update(data).digest(outputEncoding))
12 changes: 12 additions & 0 deletions crypto/polyfill/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "@pnpm/tsconfig",
"compilerOptions": {
"outDir": "lib",
"rootDir": "src"
},
"include": [
"src/**/*.ts",
"../../__typings__/**/*.d.ts"
],
"references": []
}
8 changes: 8 additions & 0 deletions crypto/polyfill/tsconfig.lint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"include": [
"src/**/*.ts",
"test/**/*.ts",
"../../__typings__/**/*.d.ts"
]
}
1 change: 1 addition & 0 deletions packages/crypto.base32-hash/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
},
"homepage": "https://github.com/pnpm/pnpm/blob/main/packages/crypto.base32-hash#readme",
"dependencies": {
"@pnpm/crypto.polyfill": "workspace:*",
"rfc4648": "catalog:"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions packages/crypto.base32-hash/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import crypto from 'crypto'
import * as crypto from '@pnpm/crypto.polyfill'
import fs from 'fs'
import { base32 } from 'rfc4648'

export function createBase32Hash (str: string): string {
return base32.stringify(crypto.createHash('md5').update(str).digest()).replace(/(=+)$/, '').toLowerCase()
return base32.stringify(crypto.hash('md5', str, 'buffer')).replace(/(=+)$/, '').toLowerCase()
}

export async function createBase32HashFromFile (file: string): Promise<string> {
Expand Down
3 changes: 3 additions & 0 deletions packages/crypto.base32-hash/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
"references": [
{
"path": "../../__utils__/prepare"
},
{
"path": "../../crypto/polyfill"
}
]
}
1 change: 1 addition & 0 deletions pkg-manager/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@pnpm/constants": "workspace:*",
"@pnpm/core-loggers": "workspace:*",
"@pnpm/crypto.base32-hash": "workspace:*",
"@pnpm/crypto.polyfill": "workspace:*",
"@pnpm/dependency-path": "workspace:*",
"@pnpm/deps.graph-sequencer": "workspace:*",
"@pnpm/error": "workspace:*",
Expand Down
4 changes: 2 additions & 2 deletions pkg-manager/core/src/install/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import crypto from 'crypto'
import path from 'path'
import { buildModules, type DepsStateCache, linkBinsOfDependencies } from '@pnpm/build-modules'
import { createAllowBuildFunction } from '@pnpm/builder.policy'
Expand All @@ -14,6 +13,7 @@ import {
stageLogger,
summaryLogger,
} from '@pnpm/core-loggers'
import * as crypto from '@pnpm/crypto.polyfill'
import {
calcPatchHashes,
createOverridesMapFromParsed,
Expand Down Expand Up @@ -746,7 +746,7 @@ Note that in CI environments, this setting is enabled by default.`,

export function createObjectChecksum (obj: Record<string, unknown>): string {
const s = JSON.stringify(sortKeys(obj, { deep: true }))
return crypto.createHash('md5').update(s).digest('hex')
return crypto.hash('md5', s, 'hex')
}

function cacheExpired (prunedAt: string, maxAgeInMinutes: number): boolean {
Expand Down
3 changes: 3 additions & 0 deletions pkg-manager/core/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
{
"path": "../../crypto/object-hasher"
},
{
"path": "../../crypto/polyfill"
},
{
"path": "../../deps/graph-sequencer"
},
Expand Down
21 changes: 21 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions resolving/npm-resolver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"dependencies": {
"@pnpm/constants": "workspace:*",
"@pnpm/core-loggers": "workspace:*",
"@pnpm/crypto.polyfill": "workspace:*",
"@pnpm/error": "workspace:*",
"@pnpm/fetching-types": "workspace:*",
"@pnpm/graceful-fs": "workspace:*",
Expand Down
4 changes: 2 additions & 2 deletions resolving/npm-resolver/src/pickPackage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import crypto from 'crypto'
import { promises as fs } from 'fs'
import path from 'path'
import * as crypto from '@pnpm/crypto.polyfill'
import { PnpmError } from '@pnpm/error'
import { logger } from '@pnpm/logger'
import gfs from '@pnpm/graceful-fs'
Expand Down Expand Up @@ -270,7 +270,7 @@ function clearMeta (pkg: PackageMeta): PackageMeta {

function encodePkgName (pkgName: string): string {
if (pkgName !== pkgName.toLowerCase()) {
return `${pkgName}_${crypto.createHash('md5').update(pkgName).digest('hex')}`
return `${pkgName}_${crypto.hash('md5', pkgName, 'hex')}`
}
return pkgName
}
Expand Down
3 changes: 3 additions & 0 deletions resolving/npm-resolver/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
{
"path": "../../__utils__/test-fixtures"
},
{
"path": "../../crypto/polyfill"
},
{
"path": "../../fs/graceful-fs"
},
Expand Down
1 change: 1 addition & 0 deletions reviewing/list/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
},
"homepage": "https://github.com/pnpm/pnpm/blob/main/reviewing/list#readme",
"dependencies": {
"@pnpm/crypto.polyfill": "workspace:*",
"@pnpm/read-package-json": "workspace:*",
"@pnpm/read-project-manifest": "workspace:*",
"@pnpm/reviewing.dependencies-hierarchy": "workspace:*",
Expand Down
4 changes: 2 additions & 2 deletions reviewing/list/src/pruneTree.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as crypto from '@pnpm/crypto.polyfill'
import { type DependenciesHierarchy, type PackageNode } from '@pnpm/reviewing.dependencies-hierarchy'
import { type PackageDependencyHierarchy } from './types'
import { createHash } from 'crypto'

export function pruneDependenciesTrees (trees: PackageDependencyHierarchy[] | null, limit: number): PackageDependencyHierarchy[] {
if (trees === null) {
Expand Down Expand Up @@ -57,7 +57,7 @@ export function pruneDependenciesTrees (trees: PackageDependencyHierarchy[] | nu

for (const node of path) {
pathSoFar += `${node.name}@${node.version},`
const id = createHash('sha256').update(pathSoFar).digest('hex')
const id = crypto.hash('sha256', pathSoFar, 'hex')
let existingNode = map.get(id)

if (!existingNode) {
Expand Down
3 changes: 3 additions & 0 deletions reviewing/list/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
{
"path": "../../__utils__/test-fixtures"
},
{
"path": "../../crypto/polyfill"
},
{
"path": "../../packages/types"
},
Expand Down
1 change: 1 addition & 0 deletions worker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"dependencies": {
"@pnpm/cafs-types": "workspace:*",
"@pnpm/create-cafs-store": "workspace:*",
"@pnpm/crypto.polyfill": "workspace:*",
"@pnpm/error": "workspace:*",
"@pnpm/exec.pkg-requires-build": "workspace:*",
"@pnpm/fs.hard-link-dir": "workspace:*",
Expand Down
4 changes: 2 additions & 2 deletions worker/src/worker.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import path from 'path'
import fs from 'fs'
import gfs from '@pnpm/graceful-fs'
import * as crypto from 'crypto'
import { type Cafs } from '@pnpm/cafs-types'
import { createCafsStore } from '@pnpm/create-cafs-store'
import * as crypto from '@pnpm/crypto.polyfill'
import { pkgRequiresBuild } from '@pnpm/exec.pkg-requires-build'
import { hardLinkDir } from '@pnpm/fs.hard-link-dir'
import {
Expand Down Expand Up @@ -129,7 +129,7 @@ function addTarballToStore ({ buffer, cafsDir, integrity, filesIndexFile }: Tarb
// Compensate for the possibility of non-uniform Base64 padding
const normalizedRemoteHash: string = Buffer.from(integrityHash, 'base64').toString('hex')

const calculatedHash: string = crypto.createHash(algo).update(buffer).digest('hex')
const calculatedHash: string = crypto.hash(algo, buffer, 'hex')
if (calculatedHash !== normalizedRemoteHash) {
return {
status: 'error',
Expand Down
3 changes: 3 additions & 0 deletions worker/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"../../__typings__/**/*.d.ts"
],
"references": [
{
"path": "../crypto/polyfill"
},
{
"path": "../exec/pkg-requires-build"
},
Expand Down
Loading