From cbfbdb43401606809cf504d616b4eb73bc346a50 Mon Sep 17 00:00:00 2001 From: Thijs Louisse Date: Thu, 16 May 2024 14:07:58 +0200 Subject: [PATCH] fix: cache and performance improvements --- .changeset/cuddly-readers-knock.md | 6 ++++++ .../src/program/core/InputDataService.js | 3 ++- .../src/program/core/ReportService.js | 5 ----- .../src/program/utils/memoize.js | 13 ++++++------- .../src/program/utils/optimised-glob.js | 14 ++++++-------- .../program/analyzers/find-imports.test.js | 1 + .../test-node/program/utils/memoize.test.js | 2 ++ 7 files changed, 23 insertions(+), 21 deletions(-) create mode 100644 .changeset/cuddly-readers-knock.md diff --git a/.changeset/cuddly-readers-knock.md b/.changeset/cuddly-readers-knock.md new file mode 100644 index 000000000..51ae97f5e --- /dev/null +++ b/.changeset/cuddly-readers-knock.md @@ -0,0 +1,6 @@ +--- +'providence-analytics': patch +--- + +- feat: expose ReportService to allow config of outputPath +- fix: cache and performance improvements diff --git a/packages-node/providence-analytics/src/program/core/InputDataService.js b/packages-node/providence-analytics/src/program/core/InputDataService.js index 6dece4332..5a1446713 100644 --- a/packages-node/providence-analytics/src/program/core/InputDataService.js +++ b/packages-node/providence-analytics/src/program/core/InputDataService.js @@ -526,7 +526,7 @@ export class InputDataService { npmGlobs.push(...getNpmPackagePaths(startPath)); } - const combinedGlobs = [...cfg.allowlist, ...npmGlobs, ...negativeGitGlobs]; + const combinedGlobs = Array.from(new Set([...cfg.allowlist, ...npmGlobs, ...negativeGitGlobs])); const hasProvidedPositiveGlob = cfg.allowlist.some(glob => !glob.startsWith('!')); // We need to expand @@ -538,6 +538,7 @@ export class InputDataService { const globbyCfg = { expandDirectories: false, + fs: fsAdapter.fs, onlyFiles: true, absolute: true, cwd: startPath, diff --git a/packages-node/providence-analytics/src/program/core/ReportService.js b/packages-node/providence-analytics/src/program/core/ReportService.js index 82944bf60..cff601771 100644 --- a/packages-node/providence-analytics/src/program/core/ReportService.js +++ b/packages-node/providence-analytics/src/program/core/ReportService.js @@ -2,9 +2,6 @@ import path from 'path'; import { hash } from '../utils/hash.js'; import { fsAdapter } from '../utils/fs-adapter.js'; -import { memoize } from '../utils/memoize.js'; -// const memoize = fn => fn; - /** * @typedef {import('../../../types/index.js').AnalyzerQueryResult} AnalyzerQueryResult * @typedef {import('../../../types/index.js').PathFromSystemRoot} PathFromSystemRoot @@ -132,5 +129,3 @@ export class ReportService { fsAdapter.fs.writeFileSync(filePath, JSON.stringify(file, null, 2), { flag: 'w' }); } } -ReportService.createIdentifier = memoize(ReportService.createIdentifier); -ReportService.getCachedResult = memoize(ReportService.getCachedResult); diff --git a/packages-node/providence-analytics/src/program/utils/memoize.js b/packages-node/providence-analytics/src/program/utils/memoize.js index d6ceda055..64c7927be 100644 --- a/packages-node/providence-analytics/src/program/utils/memoize.js +++ b/packages-node/providence-analytics/src/program/utils/memoize.js @@ -24,16 +24,16 @@ function createCachableArg(arg) { /** * @template T - * @type {(functionToMemoize:T, opts?:{ storage?:object; serializeObjects?: boolean }) => T} + * @type {(functionToMemoize:T, opts?:{ storage?:object; }) => T} */ -export function memoize(functionToMemoize, { storage = {}, serializeObjects = false } = {}) { - // @ts-expect-erro - // eslint-disable-next-line func-names +export function memoize(functionToMemoize, { storage = {} } = {}) { return /** @type {* & T} */ ( function memoizedFn() { // eslint-disable-next-line prefer-rest-params const args = [...arguments]; - const cachableArgs = !serializeObjects ? args : args.map(createCachableArg); + const shouldSerialize = args.some(isObject); + + const cachableArgs = shouldSerialize ? args.map(createCachableArg) : args; // Allow disabling of cache for testing purposes // @ts-expect-error if (shouldCache && cachableArgs in storage) { @@ -56,6 +56,7 @@ export function memoize(functionToMemoize, { storage = {}, serializeObjects = fa memoize.disableCaching = () => { shouldCache = false; }; + /** * Once testing is done, it is possible to restore caching. * @param {boolean} [initialValue] @@ -65,8 +66,6 @@ memoize.restoreCaching = initialValue => { }; Object.defineProperty(memoize, 'isCacheEnabled', { - // writable: false, - // enumerable: true, get() { return shouldCache; }, diff --git a/packages-node/providence-analytics/src/program/utils/optimised-glob.js b/packages-node/providence-analytics/src/program/utils/optimised-glob.js index 24dcecb9e..7cc3b9e03 100644 --- a/packages-node/providence-analytics/src/program/utils/optimised-glob.js +++ b/packages-node/providence-analytics/src/program/utils/optimised-glob.js @@ -141,7 +141,7 @@ async function getAllFilesFromStartPath( const direntsForLvl = await fs.promises.readdir(startPath, { withFileTypes: true }); for (const dirent of direntsForLvl) { // @ts-expect-error - dirent.parentPath = startPath; + dirent.parentPath = dirent.path = startPath; // eslint-disable-line no-multi-assign dirents.push(dirent); if (dirent.isDirectory()) { @@ -189,7 +189,7 @@ export async function optimisedGlob(globOrGlobs, providedOptions = {}) { options.onlyDirectories = true; } - const globs = Array.isArray(globOrGlobs) ? globOrGlobs : [globOrGlobs]; + const globs = Array.isArray(globOrGlobs) ? Array.from(new Set(globOrGlobs)) : [globOrGlobs]; /** @type {RegExp[]} */ const matchRegexesNegative = []; @@ -224,12 +224,10 @@ export async function optimisedGlob(globOrGlobs, providedOptions = {}) { }); const allDirEntsRelativeToCwd = allDirentsRelativeToStartPath.map(dirent => ({ - // @ts-expect-error - relativeToCwdPath: toPosixPath(path.join(dirent.parentPath, dirent.name)).replace( - `${toPosixPath(options.cwd)}/`, - '', - ), - + relativeToCwdPath: toPosixPath( + // @ts-expect-error + path.join(dirent.parentPath || dirent.path, dirent.name), + ).replace(`${toPosixPath(options.cwd)}/`, ''), dirent, })); diff --git a/packages-node/providence-analytics/test-node/program/analyzers/find-imports.test.js b/packages-node/providence-analytics/test-node/program/analyzers/find-imports.test.js index fc1bb3a9f..1da643c2f 100644 --- a/packages-node/providence-analytics/test-node/program/analyzers/find-imports.test.js +++ b/packages-node/providence-analytics/test-node/program/analyzers/find-imports.test.js @@ -1,5 +1,6 @@ import { expect } from 'chai'; import { it } from 'mocha'; + import { providence } from '../../../src/program/providence.js'; import { QueryService } from '../../../src/program/core/QueryService.js'; import { setupAnalyzerTest } from '../../../test-helpers/setup-analyzer-test.js'; diff --git a/packages-node/providence-analytics/test-node/program/utils/memoize.test.js b/packages-node/providence-analytics/test-node/program/utils/memoize.test.js index 1e70c1fa0..573726f3c 100644 --- a/packages-node/providence-analytics/test-node/program/utils/memoize.test.js +++ b/packages-node/providence-analytics/test-node/program/utils/memoize.test.js @@ -119,6 +119,7 @@ describe('Memoize', () => { }); }); }); + describe('With non primitives', () => { describe('Arrays', () => { it(`returns cached result when called with same parameters`, async () => { @@ -246,6 +247,7 @@ describe('Memoize', () => { expect(sumCalled).to.equal(1); // Outside world can edit returned reference + // @ts-expect-error resultCached.x = 3; // Return from cache const lastResult = sumMemoized({ x: 1 }, { y: 2 });