Skip to content

Commit 7c01898

Browse files
authored
perf: improve global cache (#907)
* perf: improve global cache * refactor: improve prop names * chore: improve `watch` cache
1 parent 3823848 commit 7c01898

File tree

18 files changed

+177
-215
lines changed

18 files changed

+177
-215
lines changed

benchmark/benchmark.sh

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ SHORT_SHA=$(git rev-parse --short HEAD)
55
echo '### 🚀 Benchmark Results\n'
66
echo '```'
77

8-
hyperfine -i --warmup 3 --export-json results.json \
8+
hyperfine -i --warmup 5 --export-json results.json \
99
--command-name "🐷 Poku ($SHORT_SHA)" '../lib/bin/index.js ./test/poku' \
1010
--command-name 'Mocha (10.7.3)' './node_modules/mocha/bin/mocha.js --parallel ./test/mocha' \
1111
--command-name 'Jest (29.7.0)' 'node --experimental-vm-modules ./node_modules/jest/bin/jest.js ./test/jest' \
@@ -19,7 +19,7 @@ echo '#### 🐢 Comparative with Node.js\n'
1919
echo '```'
2020

2121
# Not included in results.json
22-
hyperfine -i --warmup 3 \
22+
hyperfine -i --warmup 5 \
2323
--command-name 'Node.js' 'node --test "./test/node/**.spec.js"' \
2424
--command-name "🐷 Poku ($SHORT_SHA)" '../lib/bin/index.js ./test/poku' |
2525
awk '/Summary/ {flag=1} flag'
@@ -29,7 +29,7 @@ echo '#### 🍞 Comparative with Bun\n'
2929
echo '```'
3030

3131
# Not included in results.json
32-
hyperfine -i --warmup 3 \
32+
hyperfine -i --warmup 5 \
3333
--command-name 'Bun' 'bun test "test/bun/"' \
3434
--command-name "🐷 Poku ($SHORT_SHA)" 'bun ../lib/bin/index.js ./test/poku' |
3535
awk '/Summary/ {flag=1} flag'

src/bin/index.ts

+28-28
Original file line numberDiff line numberDiff line change
@@ -24,38 +24,38 @@ import { GLOBAL, VERSION } from '../configs/poku.js';
2424
const enforce = hasArg('enforce') || hasArg('x', '-');
2525
const configFile = getArg('config') || getArg('c', '-');
2626

27-
GLOBAL.defaultConfigs = await getConfigs(configFile);
28-
const { defaultConfigs } = GLOBAL;
27+
GLOBAL.configsFromFile = await getConfigs(configFile);
2928

29+
const { configsFromFile } = GLOBAL;
3030
const dirs: string[] =
3131
getPaths('-') ??
32-
(defaultConfigs?.include
33-
? Array.prototype.concat(defaultConfigs?.include)
32+
(configsFromFile?.include
33+
? Array.prototype.concat(configsFromFile?.include)
3434
: ['.']);
35-
const filter = getArg('filter') ?? defaultConfigs?.filter;
36-
const exclude = getArg('exclude') ?? defaultConfigs?.exclude;
35+
const filter = getArg('filter') ?? configsFromFile?.filter;
36+
const exclude = getArg('exclude') ?? configsFromFile?.exclude;
3737
const killPort = getArg('killPort');
3838
const killRange = getArg('killRange');
3939
const killPID = getArg('killPid');
4040
/* c8 ignore start */ // Deno
41-
const denoAllow = argToArray('denoAllow') ?? defaultConfigs?.deno?.allow;
42-
const denoDeny = argToArray('denoDeny') ?? defaultConfigs?.deno?.deny;
41+
const denoAllow = argToArray('denoAllow') ?? configsFromFile?.deno?.allow;
42+
const denoDeny = argToArray('denoDeny') ?? configsFromFile?.deno?.deny;
4343
const denoCJS =
4444
getArg('denoCjs')
4545
?.split(',')
4646
.map((a) => a.trim())
4747
.filter((a) => a) ||
4848
hasArg('denoCjs') ||
49-
defaultConfigs?.deno?.cjs;
49+
configsFromFile?.deno?.cjs;
5050
/* c8 ignore stop */
51-
const quiet = hasArg('quiet') || hasArg('q', '-') || defaultConfigs?.quiet;
52-
const debug = hasArg('debug') || hasArg('d', '-') || defaultConfigs?.debug;
53-
const failFast = hasArg('failFast') || defaultConfigs?.failFast;
51+
const quiet = hasArg('quiet') || hasArg('q', '-') || configsFromFile?.quiet;
52+
const debug = hasArg('debug') || hasArg('d', '-') || configsFromFile?.debug;
53+
const failFast = hasArg('failFast') || configsFromFile?.failFast;
5454
const watchMode = hasArg('watch') || hasArg('w', '-');
5555
const hasEnvFile = hasArg('envFile');
5656
const concurrency = (() => {
5757
const value = Number(getArg('concurrency'));
58-
return Number.isNaN(value) ? defaultConfigs?.concurrency : value;
58+
return Number.isNaN(value) ? configsFromFile?.concurrency : value;
5959
})();
6060
const sequential = hasArg('sequential');
6161

@@ -96,7 +96,7 @@ import { GLOBAL, VERSION } from '../configs/poku.js';
9696
}
9797

9898
GLOBAL.configFile = configFile;
99-
GLOBAL.options = {
99+
GLOBAL.configs = {
100100
filter:
101101
typeof filter === 'string' ? new RegExp(escapeRegExp(filter)) : filter,
102102
exclude:
@@ -113,30 +113,30 @@ import { GLOBAL, VERSION } from '../configs/poku.js';
113113
},
114114
noExit: watchMode,
115115
beforeEach:
116-
'beforeEach' in defaultConfigs ? defaultConfigs.beforeEach : undefined,
116+
'beforeEach' in configsFromFile ? configsFromFile.beforeEach : undefined,
117117
afterEach:
118-
'afterEach' in defaultConfigs ? defaultConfigs.afterEach : undefined,
118+
'afterEach' in configsFromFile ? configsFromFile.afterEach : undefined,
119119
};
120120

121121
const tasks: Promise<unknown>[] = [];
122122

123-
if (hasEnvFile || defaultConfigs?.envFile) {
124-
GLOBAL.envFile = getArg('envFile') ?? defaultConfigs?.envFile ?? '.env';
123+
if (hasEnvFile || configsFromFile?.envFile) {
124+
GLOBAL.envFile = getArg('envFile') ?? configsFromFile?.envFile ?? '.env';
125125
}
126126

127127
if (enforce) require('../services/enforce.js').enforce();
128128

129129
/* c8 ignore start */ // Process-based
130-
if (killPort || defaultConfigs?.kill?.port) {
130+
if (killPort || configsFromFile?.kill?.port) {
131131
const ports =
132-
killPort?.split(',').map(Number) || defaultConfigs?.kill?.port || [];
132+
killPort?.split(',').map(Number) || configsFromFile?.kill?.port || [];
133133
tasks.push(kill.port(ports));
134134
}
135135

136-
if (killRange || defaultConfigs?.kill?.range) {
136+
if (killRange || configsFromFile?.kill?.range) {
137137
const ranges =
138138
killRange?.split(',') ||
139-
defaultConfigs?.kill?.range?.map((range) => `${range[0]}-${range[1]}`) ||
139+
configsFromFile?.kill?.range?.map((range) => `${range[0]}-${range[1]}`) ||
140140
[];
141141

142142
for (const range of ranges) {
@@ -147,28 +147,28 @@ import { GLOBAL, VERSION } from '../configs/poku.js';
147147
}
148148
}
149149

150-
if (killPID || defaultConfigs?.kill?.pid) {
150+
if (killPID || configsFromFile?.kill?.pid) {
151151
const PIDs =
152-
killPID?.split(',').map(Number) || defaultConfigs?.kill?.pid || [];
152+
killPID?.split(',').map(Number) || configsFromFile?.kill?.pid || [];
153153

154154
tasks.push(kill.pid(PIDs));
155155
}
156156
/* c8 ignore stop */
157157

158158
GLOBAL.envFile && tasks.push(envFile(GLOBAL.envFile));
159159

160-
if (debug || defaultConfigs?.debug) {
160+
if (debug || configsFromFile?.debug) {
161161
hr();
162162
log(`${format(' Debug Enabled ').bg('brightBlue')}\n`);
163163
log(`${format('…').info().italic()} ${format('Paths').bold()}`);
164164
console.table(dirs);
165165
log('\n');
166166
log(`${format('…').info().italic()} ${format('Options').bold()}`);
167-
console.dir(GLOBAL.options, { depth: null, colors: true });
167+
console.dir(GLOBAL.configs, { depth: null, colors: true });
168168
}
169169

170170
await Promise.all(tasks);
171-
await poku(dirs, GLOBAL.options);
171+
await poku(dirs);
172172

173-
if (watchMode) await require('./watch.js').startWatch(dirs, GLOBAL.options);
173+
if (watchMode) await require('./watch.js').startWatch(dirs);
174174
})();

src/bin/watch.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import { watch, type Watcher } from '../services/watch.js';
33
import { onSigint, poku } from '../modules/essentials/poku.js';
44
import { log, hr } from '../services/write.js';
55
import process from 'node:process';
6-
import type { Configs } from '../@types/poku.js';
76
import { format } from '../services/format.js';
87
import { getArg } from '../parsers/get-arg.js';
98
import { fileResults } from '../configs/files.js';
109
import { availableParallelism } from '../polyfills/os.js';
10+
import { GLOBAL } from '../configs/poku.js';
1111

12-
export const startWatch = async (dirs: string[], options: Configs) => {
12+
export const startWatch = async (dirs: string[]) => {
1313
let isRunning = false;
1414

1515
const watchers: Set<Watcher> = new Set();
@@ -33,7 +33,7 @@ export const startWatch = async (dirs: string[], options: Configs) => {
3333

3434
watchers.clear();
3535
resultsClear();
36-
await poku(dirs, options);
36+
await poku(dirs);
3737
}
3838
};
3939

@@ -44,8 +44,8 @@ export const startWatch = async (dirs: string[], options: Configs) => {
4444
const mappedTests = await mapTests(
4545
'.',
4646
dirs,
47-
options.filter,
48-
options.exclude
47+
GLOBAL.configs.filter,
48+
GLOBAL.configs.exclude
4949
);
5050

5151
for (const mappedTest of Array.from(mappedTests.keys())) {
@@ -62,9 +62,9 @@ export const startWatch = async (dirs: string[], options: Configs) => {
6262
if (!tests) return;
6363

6464
await poku(Array.from(tests), {
65-
...options,
65+
...GLOBAL.configs,
6666
concurrency:
67-
options.concurrency ??
67+
GLOBAL.configs.concurrency ??
6868
Math.max(Math.floor(availableParallelism() / 2), 1),
6969
});
7070

@@ -87,7 +87,7 @@ export const startWatch = async (dirs: string[], options: Configs) => {
8787
executing.add(file);
8888
resultsClear();
8989

90-
poku(file, options).then(() =>
90+
poku(file).then(() =>
9191
setTimeout(() => {
9292
executing.delete(file);
9393
setIsRunning(false);

src/configs/poku.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ export const deepOptions: string[] = [];
1414

1515
export const GLOBAL = {
1616
cwd: cwd(),
17-
runAsOnly: false,
17+
configs: Object.create(null) as Configs,
18+
configFile: undefined as string | undefined,
19+
configsFromFile: Object.create(null) as ConfigFile | ConfigJSONFile,
1820
isPoku: typeof env?.POKU_FILE === 'string' && env?.POKU_FILE.length > 0,
1921
FILE: env.POKU_FILE,
20-
options: Object.create(null) as Configs,
21-
configFile: undefined as string | undefined,
22-
defaultConfigs: Object.create(null) as ConfigFile | ConfigJSONFile,
2322
envFile: undefined as string | undefined,
23+
runAsOnly: false,
2424
};

src/modules/essentials/poku.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import process from 'node:process';
44
import { log, hr } from '../../services/write.js';
55
import { exit } from '../helpers/exit.js';
66
import { format, showTestResults } from '../../services/format.js';
7-
import { isQuiet } from '../../parsers/output.js';
87
import { finalResults } from '../../configs/files.js';
98
import { runTests } from '../../services/run-tests.js';
9+
import { GLOBAL } from '../../configs/poku.js';
1010

1111
/* c8 ignore start */ // Process-based
1212
export const onSigint = () => process.stdout.write('\u001B[?25h');
@@ -28,19 +28,21 @@ export async function poku(
2828
): Promise<Code | undefined> {
2929
let code: Code = 0;
3030

31+
if (configs) GLOBAL.configs = { ...GLOBAL.configs, ...configs };
32+
3133
finalResults.started = new Date();
3234

3335
const start = process.hrtime();
3436
const dirs = Array.prototype.concat(targetPaths);
35-
const showLogs = !isQuiet(configs);
37+
const showLogs = !GLOBAL.configs.quiet;
3638

3739
if (showLogs) {
3840
hr();
3941
log(`${format('Running Tests').bold()}\n`);
4042
}
4143

4244
try {
43-
const promises = dirs.map(async (dir) => await runTests(dir, configs));
45+
const promises = dirs.map(async (dir) => await runTests(dir));
4446
const concurrency = await Promise.all(promises);
4547

4648
if (concurrency.some((result) => !result)) code = 1;
@@ -53,7 +55,7 @@ export async function poku(
5355

5456
showLogs && showTestResults();
5557

56-
if (configs?.noExit) return code;
58+
if (GLOBAL.configs.noExit) return code;
5759

58-
exit(code, configs?.quiet);
60+
exit(code, GLOBAL.configs.quiet);
5961
}

src/parsers/get-runner.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
import type { Configs } from '../@types/poku.js';
21
import type { Runner } from '../@types/runner.js';
32
import { platform } from 'node:process';
43
import { extname } from 'node:path';
54
import { getRuntime } from './get-runtime.js';
5+
import { GLOBAL } from '../configs/poku.js';
66

77
export const isWindows = platform === 'win32';
88

9-
export const runner = (filename: string, configs?: Configs): string[] => {
9+
export const runner = (filename: string): string[] => {
1010
const runtime = getRuntime();
1111

1212
if (runtime === 'bun') return ['bun'];
1313

1414
if (runtime === 'deno') {
15-
const denoAllow = configs?.deno?.allow
16-
? configs.deno.allow
15+
const denoAllow = GLOBAL.configs.deno?.allow
16+
? GLOBAL.configs.deno.allow
1717
.map((allow) => (allow ? `--allow-${allow}` : ''))
1818
.filter((allow) => allow)
1919
: ['--allow-read', '--allow-env', '--allow-run', '--allow-net'];
2020

21-
const denoDeny = configs?.deno?.deny
22-
? configs.deno.deny
21+
const denoDeny = GLOBAL.configs.deno?.deny
22+
? GLOBAL.configs.deno.deny
2323
.map((deny) => (deny ? `--deny-${deny}` : ''))
2424
.filter((deny) => deny)
2525
: [];

src/parsers/output.ts

+4-15
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
1-
import type { Configs } from '../@types/poku.js';
2-
import { results } from '../configs/poku.js';
1+
import { GLOBAL, results } from '../configs/poku.js';
32

43
const regex = {
54
ansi: /u001b\[0m|\n/i,
65
skip: /\\u001b\[94m\\u001b\[1m/gi,
76
todo: /\\u001b\[96m\\u001b\[1m/gi,
87
} as const;
98

10-
export const isQuiet = (configs?: Configs): boolean =>
11-
typeof configs?.quiet === 'boolean' && Boolean(configs?.quiet);
12-
13-
export const isDebug = (configs?: Configs): boolean => Boolean(configs?.debug);
14-
15-
export const parserOutput = (options: {
16-
output: string;
17-
result: boolean;
18-
configs?: Configs;
19-
}) => {
20-
const { output, result, configs } = options;
9+
export const parserOutput = (options: { output: string; result: boolean }) => {
10+
const { output, result } = options;
2111
const normalizedOutput = JSON.stringify(output);
2212

2313
const hasSkip = normalizedOutput.match(regex.skip);
@@ -26,12 +16,11 @@ export const parserOutput = (options: {
2616
const hasTodo = normalizedOutput.match(regex.todo);
2717
if (hasTodo) results.todo += hasTodo.length;
2818

29-
const debug = isDebug(configs);
3019
const pad = ' ';
3120
const splittedOutput = output.split('\n');
3221

3322
const outputs = (
34-
debug || !result
23+
GLOBAL.configs.debug || !result
3524
? splittedOutput
3625
: splittedOutput.filter((current) => {
3726
if (current.indexOf('Exited with code') !== -1) return false;

src/services/each.ts

+11-12
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import type { Configs } from '../@types/poku.js';
22
import { format } from './format.js';
33
import { log } from '../services/write.js';
4-
import { isQuiet } from '../parsers/output.js';
4+
import { GLOBAL } from '../configs/poku.js';
55

66
const eachCore = async (
77
type: keyof Required<Pick<Configs, 'beforeEach' | 'afterEach'>>,
8-
fileRelative: string,
9-
configs?: Configs
8+
fileRelative: string
109
): Promise<boolean> => {
11-
if (typeof configs?.[type] !== 'function') return true;
10+
if (typeof GLOBAL.configs?.[type] !== 'function') return true;
1211

13-
const cb = configs[type];
14-
const showLogs = !isQuiet(configs);
12+
const cb = GLOBAL.configs[type];
13+
const showLogs = !GLOBAL.configs.quiet;
1514
const cbName = cb.name !== type ? cb.name : 'anonymous function';
1615

1716
showLogs &&
@@ -47,16 +46,16 @@ const eachCore = async (
4746
}
4847
};
4948

50-
export const beforeEach = async (fileRelative: string, configs?: Configs) => {
51-
if (configs?.beforeEach)
52-
return await eachCore('beforeEach', fileRelative, configs);
49+
export const beforeEach = async (fileRelative: string) => {
50+
if (GLOBAL.configs.beforeEach)
51+
return await eachCore('beforeEach', fileRelative);
5352

5453
return true;
5554
};
5655

57-
export const afterEach = async (fileRelative: string, configs?: Configs) => {
58-
if (configs?.afterEach)
59-
return await eachCore('afterEach', fileRelative, configs);
56+
export const afterEach = async (fileRelative: string) => {
57+
if (GLOBAL.configs.afterEach)
58+
return await eachCore('afterEach', fileRelative);
6059

6160
return true;
6261
};

0 commit comments

Comments
 (0)