From 0f81e6db47503688e0cdc56b4bf15aab36fd426d Mon Sep 17 00:00:00 2001 From: Raine Revere Date: Wed, 20 Jan 2021 17:06:42 -0700 Subject: [PATCH] Memoize viewMany. Fixes #790. --- lib/constants.js | 5 +---- lib/index.js | 5 +---- lib/package-managers/npm.js | 12 ++++++++++-- lib/package-managers/yarn.js | 4 ++-- package-lock.json | 27 +++++++++++++++++++++++++++ package.json | 1 + 6 files changed, 42 insertions(+), 12 deletions(-) diff --git a/lib/constants.js b/lib/constants.js index 5630c1b9..ec12b580 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -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 } diff --git a/lib/index.js b/lib/index.js index 876a111a..04518c03 100644 --- a/lib/index.js +++ b/lib/index.js @@ -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 @@ -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 diff --git a/lib/package-managers/npm.js b/lib/package-managers/npm.js index 9ea86ac5..0b844ed7 100644 --- a/lib/package-managers/npm.js +++ b/lib/package-managers/npm.js @@ -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') @@ -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] } @@ -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. * @@ -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) @@ -349,4 +356,5 @@ module.exports = { packageAuthorChanged, viewOne, viewMany, + viewManyMemoized, } diff --git a/lib/package-managers/yarn.js b/lib/package-managers/yarn.js index 357ead7a..387ebe26 100644 --- a/lib/package-managers/yarn.js +++ b/lib/package-managers/yarn.js @@ -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'] @@ -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) diff --git a/package-lock.json b/package-lock.json index 6a53619c..f791b707 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3235,6 +3235,23 @@ "ssri": "^8.0.0" } }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-8.0.0.tgz", + "integrity": "sha512-qrcJOe6uD+EW8Wrci1Vdiua/15Xw3n/QnaNXE7varnB6InxSk7nu3/i5jfy3S6kWxr8WYJ6R1o0afMUtvorTsA==", + "requires": { + "map-age-cleaner": "^0.1.3", + "mimic-fn": "^3.1.0" + } + }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3262,6 +3279,11 @@ "mime-db": "1.45.0" } }, + "mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==" + }, "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", @@ -3869,6 +3891,11 @@ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", diff --git a/package.json b/package.json index 727ce7ca..978799af 100644 --- a/package.json +++ b/package.json @@ -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",