Skip to content

Commit

Permalink
Memoize viewMany. Fixes #790.
Browse files Browse the repository at this point in the history
  • Loading branch information
raineorshine committed Jan 21, 2021
1 parent 22648fd commit 0f81e6d
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 12 deletions.
5 changes: 1 addition & 4 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,4 @@ Saving partially upgraded package.json

const deepPatternPrefix = '**/'

const deepPerfWarning = `--deep is slow and can have performance impact when there are lot of packages!
See https://github.com/raineorshine/npm-check-updates/pull/785 for more information!`

module.exports = { deepPatternPrefix, deepPerfWarning, doctorHelpText, supportedVersionTargets }
module.exports = { deepPatternPrefix, doctorHelpText, supportedVersionTargets }
5 changes: 1 addition & 4 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const vm = require('./versionmanager')
const doctor = require('./doctor')
const packageManagers = require('./package-managers')
const { print, printJson, printUpgrades } = require('./logging')
const { deepPatternPrefix, deepPerfWarning, doctorHelpText } = require('./constants')
const { deepPatternPrefix, doctorHelpText } = require('./constants')
const cliOptions = require('./cli-options')

// maps package managers to package file names
Expand Down Expand Up @@ -439,9 +439,6 @@ async function run(options = {}) {
return analysis
}
else if (options.deep) {
if (pkgs.length > 0) {
print(options, chalk.yellow(deepPerfWarning), 'warn')
}
analysis = await pkgs.reduce(async (previousPromise, packageFile) => {
const packages = await previousPromise
// Mutate packageFile for current package
Expand Down
12 changes: 10 additions & 2 deletions lib/package-managers/npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const fs = require('fs')
const semver = require('semver')
const spawn = require('spawn-please')
const pacote = require('pacote')
const mem = require('mem')
const libnpmconfig = require('libnpmconfig')
const versionUtil = require('../version-util')
const { print } = require('../logging')
Expand Down Expand Up @@ -112,7 +113,7 @@ async function packageAuthorChanged(packageName, currentVersion, upgradedVersion
* @returns Promised result
*/
async function viewOne(packageName, field, currentVersion, { timeout } = {}) {
const result = await viewMany(packageName, [field], currentVersion, { timeout })
const result = await viewManyMemoized(packageName, [field], currentVersion, { timeout })
return result && result[field]
}

Expand Down Expand Up @@ -140,6 +141,12 @@ async function viewMany(packageName, fields, currentVersion, { timeout } = {}) {
}), {})
}

/** Memoize viewMany for --deep performance. */
const viewManyMemoized = mem(viewMany, {
cacheKey: ([packageName, fields, currentVersion]) =>
`${packageName}|${fields.join('|')}|${currentVersion}`
})

/**
* Returns true if the node engine requirement is satisfied or not specified for a given package version.
*
Expand Down Expand Up @@ -281,7 +288,7 @@ module.exports = {
*/
async newest(packageName, currentVersion, options = {}) {

const result = await viewMany(packageName, ['time', 'versions'], currentVersion, { timeout: options.timeout })
const result = await viewManyMemoized(packageName, ['time', 'versions'], currentVersion, { timeout: options.timeout })

const versionsSatisfyingNodeEngine = _.filter(result.versions, version => satisfiesNodeEngine(version, options.enginesNode))
.map(o => o.version)
Expand Down Expand Up @@ -349,4 +356,5 @@ module.exports = {
packageAuthorChanged,
viewOne,
viewMany,
viewManyMemoized,
}
4 changes: 2 additions & 2 deletions lib/package-managers/yarn.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const spawn = require('spawn-please')
const libnpmconfig = require('libnpmconfig')
const jsonlines = require('jsonlines')
const versionUtil = require('../version-util')
const { viewOne, viewMany } = require('./npm.js')
const { viewOne, viewManyMemoized } = require('./npm.js')

const TIME_FIELDS = ['modified', 'created']

Expand Down Expand Up @@ -216,7 +216,7 @@ module.exports = {
* @returns
*/
newest(packageName, currentVersion, options = {}) {
return viewMany(packageName, ['time', 'versions'], currentVersion,
return viewManyMemoized(packageName, ['time', 'versions'], currentVersion,
{ timeout: options.timeout }).then(result => {
const versions = doesSatisfyEnginesNode(result.versions,
options.enginesNode)
Expand Down
27 changes: 27 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"jsonlines": "^0.1.1",
"libnpmconfig": "^1.2.1",
"lodash": "^4.17.20",
"mem": "^8.0.0",
"p-map": "^4.0.0",
"pacote": "^11.2.2",
"parse-github-url": "^1.0.2",
Expand Down

0 comments on commit 0f81e6d

Please sign in to comment.