@reliverse/dler 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +3 -0
- package/dist/cmds/build/cmd.d.ts +2 -0
- package/dist/cmds/build/cmd.js +564 -0
- package/dist/cmds/clean/cmd.d.ts +2 -0
- package/dist/cmds/clean/cmd.js +146 -0
- package/dist/cmds/clean/impl.d.ts +2 -0
- package/dist/cmds/clean/impl.js +627 -0
- package/dist/cmds/clean/presets.d.ts +10 -0
- package/dist/cmds/clean/presets.js +112 -0
- package/dist/cmds/clean/types.d.ts +62 -0
- package/dist/cmds/clean/types.js +0 -0
- package/dist/cmds/init/cmd.d.ts +3 -0
- package/dist/cmds/init/cmd.js +56 -0
- package/dist/cmds/init/impl/config.d.ts +45 -0
- package/dist/cmds/init/impl/config.js +99 -0
- package/dist/cmds/init/impl/generators.d.ts +6 -0
- package/dist/cmds/init/impl/generators.js +178 -0
- package/dist/cmds/init/impl/prompts.d.ts +2 -0
- package/dist/cmds/init/impl/prompts.js +98 -0
- package/dist/cmds/init/impl/types.d.ts +22 -0
- package/dist/cmds/init/impl/types.js +0 -0
- package/dist/cmds/init/impl/utils.d.ts +4 -0
- package/dist/cmds/init/impl/utils.js +11 -0
- package/dist/cmds/init/impl/validators.d.ts +4 -0
- package/dist/cmds/init/impl/validators.js +42 -0
- package/dist/cmds/integrate/cmd.d.ts +3 -0
- package/dist/cmds/integrate/cmd.js +70 -0
- package/dist/cmds/integrate/impl.d.ts +7 -0
- package/dist/cmds/integrate/impl.js +127 -0
- package/dist/cmds/integrate/integrations/base.d.ts +13 -0
- package/dist/cmds/integrate/integrations/base.js +41 -0
- package/dist/cmds/integrate/integrations/nextjs.d.ts +16 -0
- package/dist/cmds/integrate/integrations/nextjs.js +167 -0
- package/dist/cmds/integrate/integrations/registry.d.ts +7 -0
- package/dist/cmds/integrate/integrations/registry.js +31 -0
- package/dist/cmds/integrate/integrations/ultracite.d.ts +11 -0
- package/dist/cmds/integrate/integrations/ultracite.js +40 -0
- package/dist/cmds/integrate/types.d.ts +39 -0
- package/dist/cmds/integrate/types.js +0 -0
- package/dist/cmds/integrate/utils/biome.d.ts +4 -0
- package/dist/cmds/integrate/utils/biome.js +140 -0
- package/dist/cmds/integrate/utils/context.d.ts +3 -0
- package/dist/cmds/integrate/utils/context.js +111 -0
- package/dist/cmds/integrate/utils/temp.d.ts +3 -0
- package/dist/cmds/integrate/utils/temp.js +36 -0
- package/dist/cmds/perf/analysis/bundle.d.ts +20 -0
- package/dist/cmds/perf/analysis/bundle.js +225 -0
- package/dist/cmds/perf/analysis/filesystem.d.ts +27 -0
- package/dist/cmds/perf/analysis/filesystem.js +246 -0
- package/dist/cmds/perf/analysis/monorepo.d.ts +29 -0
- package/dist/cmds/perf/analysis/monorepo.js +307 -0
- package/dist/cmds/perf/benchmarks/command.d.ts +21 -0
- package/dist/cmds/perf/benchmarks/command.js +162 -0
- package/dist/cmds/perf/benchmarks/memory.d.ts +41 -0
- package/dist/cmds/perf/benchmarks/memory.js +169 -0
- package/dist/cmds/perf/benchmarks/runner.d.ts +22 -0
- package/dist/cmds/perf/benchmarks/runner.js +157 -0
- package/dist/cmds/perf/cmd.d.ts +2 -0
- package/dist/cmds/perf/cmd.js +238 -0
- package/dist/cmds/perf/impl.d.ts +24 -0
- package/dist/cmds/perf/impl.js +304 -0
- package/dist/cmds/perf/reporters/console.d.ts +12 -0
- package/dist/cmds/perf/reporters/console.js +257 -0
- package/dist/cmds/perf/reporters/html.d.ts +27 -0
- package/dist/cmds/perf/reporters/html.js +881 -0
- package/dist/cmds/perf/reporters/json.d.ts +9 -0
- package/dist/cmds/perf/reporters/json.js +32 -0
- package/dist/cmds/perf/types.d.ts +184 -0
- package/dist/cmds/perf/types.js +0 -0
- package/dist/cmds/perf/utils/cache.d.ts +23 -0
- package/dist/cmds/perf/utils/cache.js +171 -0
- package/dist/cmds/perf/utils/formatter.d.ts +17 -0
- package/dist/cmds/perf/utils/formatter.js +134 -0
- package/dist/cmds/perf/utils/stats.d.ts +15 -0
- package/dist/cmds/perf/utils/stats.js +101 -0
- package/dist/cmds/publish/cmd.d.ts +3 -0
- package/dist/cmds/publish/cmd.js +189 -0
- package/dist/cmds/shell/cmd.d.ts +3 -0
- package/dist/cmds/shell/cmd.js +50 -0
- package/dist/cmds/tsc/cache.d.ts +27 -0
- package/dist/cmds/tsc/cache.js +160 -0
- package/dist/cmds/tsc/cmd.d.ts +2 -0
- package/dist/cmds/tsc/cmd.js +111 -0
- package/dist/cmds/tsc/impl.d.ts +41 -0
- package/dist/cmds/tsc/impl.js +572 -0
- package/dist/cmds/tsc/types.d.ts +57 -0
- package/dist/cmds/tsc/types.js +0 -0
- package/package.json +4 -11
- package/src/cli.ts +8 -0
- package/src/cmds/build/cmd.ts +582 -0
- package/src/cmds/clean/cmd.ts +166 -0
- package/src/cmds/clean/impl.ts +900 -0
- package/src/cmds/clean/presets.ts +158 -0
- package/src/cmds/clean/types.ts +71 -0
- package/src/cmds/init/cmd.ts +68 -0
- package/src/cmds/init/impl/config.ts +105 -0
- package/src/cmds/init/impl/generators.ts +220 -0
- package/src/cmds/init/impl/prompts.ts +137 -0
- package/src/cmds/init/impl/types.ts +25 -0
- package/src/cmds/init/impl/utils.ts +17 -0
- package/src/cmds/init/impl/validators.ts +55 -0
- package/src/cmds/integrate/cmd.ts +82 -0
- package/src/cmds/integrate/impl.ts +204 -0
- package/src/cmds/integrate/integrations/base.ts +69 -0
- package/src/cmds/integrate/integrations/nextjs.ts +227 -0
- package/src/cmds/integrate/integrations/registry.ts +45 -0
- package/src/cmds/integrate/integrations/ultracite.ts +53 -0
- package/src/cmds/integrate/types.ts +48 -0
- package/src/cmds/integrate/utils/biome.ts +173 -0
- package/src/cmds/integrate/utils/context.ts +148 -0
- package/src/cmds/integrate/utils/temp.ts +47 -0
- package/src/cmds/perf/analysis/bundle.ts +311 -0
- package/src/cmds/perf/analysis/filesystem.ts +324 -0
- package/src/cmds/perf/analysis/monorepo.ts +439 -0
- package/src/cmds/perf/benchmarks/command.ts +230 -0
- package/src/cmds/perf/benchmarks/memory.ts +249 -0
- package/src/cmds/perf/benchmarks/runner.ts +220 -0
- package/src/cmds/perf/cmd.ts +285 -0
- package/src/cmds/perf/impl.ts +411 -0
- package/src/cmds/perf/reporters/console.ts +331 -0
- package/src/cmds/perf/reporters/html.ts +984 -0
- package/src/cmds/perf/reporters/json.ts +42 -0
- package/src/cmds/perf/types.ts +220 -0
- package/src/cmds/perf/utils/cache.ts +234 -0
- package/src/cmds/perf/utils/formatter.ts +190 -0
- package/src/cmds/perf/utils/stats.ts +153 -0
- package/src/cmds/publish/cmd.ts +215 -0
- package/src/cmds/shell/cmd.ts +61 -0
- package/src/cmds/tsc/cache.ts +237 -0
- package/src/cmds/tsc/cmd.ts +139 -0
- package/src/cmds/tsc/impl.ts +855 -0
- package/src/cmds/tsc/types.ts +66 -0
- package/tsconfig.json +9 -0
- package/cli.js +0 -1316
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineCmd,
|
|
3
|
+
defineCmdArgs,
|
|
4
|
+
defineCmdCfg
|
|
5
|
+
} from "@reliverse/dler-launcher";
|
|
6
|
+
import { logger } from "@reliverse/dler-logger";
|
|
7
|
+
import { runPerfAnalysis } from "./impl.js";
|
|
8
|
+
import { createConsoleReporter } from "./reporters/console.js";
|
|
9
|
+
import { createHtmlReporter } from "./reporters/html.js";
|
|
10
|
+
import { createJsonReporter } from "./reporters/json.js";
|
|
11
|
+
const perfCmd = async (args) => {
|
|
12
|
+
try {
|
|
13
|
+
if (typeof process.versions.bun === "undefined") {
|
|
14
|
+
logger.error("\u274C This command requires Bun runtime. Sorry.");
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const validTypes = [
|
|
18
|
+
"command",
|
|
19
|
+
"bundle",
|
|
20
|
+
"file",
|
|
21
|
+
"monorepo",
|
|
22
|
+
"auto"
|
|
23
|
+
];
|
|
24
|
+
if (args.type && !validTypes.includes(args.type)) {
|
|
25
|
+
logger.error(
|
|
26
|
+
`\u274C Invalid type: ${args.type}. Must be one of: ${validTypes.join(", ")}`
|
|
27
|
+
);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
const validOutputs = ["console", "json", "html", "all"];
|
|
31
|
+
if (args.output && !validOutputs.includes(args.output)) {
|
|
32
|
+
logger.error(
|
|
33
|
+
`\u274C Invalid output format: ${args.output}. Must be one of: ${validOutputs.join(", ")}`
|
|
34
|
+
);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
const result = await runPerfAnalysis(args);
|
|
38
|
+
if (!result.success) {
|
|
39
|
+
logger.error(`\u274C Performance analysis failed: ${result.error}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const outputFormats = args.output === "all" ? ["console", "json", "html"] : [args.output ?? "console"];
|
|
43
|
+
for (const format of outputFormats) {
|
|
44
|
+
switch (format) {
|
|
45
|
+
case "console": {
|
|
46
|
+
const consoleReporter = createConsoleReporter(args.verbose);
|
|
47
|
+
consoleReporter.report(result.report);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
case "json": {
|
|
51
|
+
const jsonReporter = createJsonReporter();
|
|
52
|
+
jsonReporter.report(result.report);
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
case "html": {
|
|
56
|
+
const htmlReporter = createHtmlReporter();
|
|
57
|
+
htmlReporter.report(result.report);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
logger.success("\n\u2705 Performance analysis completed successfully!");
|
|
63
|
+
} catch (error) {
|
|
64
|
+
logger.error("\n\u274C Performance analysis failed:");
|
|
65
|
+
if (error instanceof Error) {
|
|
66
|
+
logger.error(error.message);
|
|
67
|
+
} else {
|
|
68
|
+
logger.error(String(error));
|
|
69
|
+
}
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const perfCmdArgs = defineCmdArgs({
|
|
74
|
+
target: {
|
|
75
|
+
type: "string",
|
|
76
|
+
description: "What to measure (command name, file path, or directory)"
|
|
77
|
+
},
|
|
78
|
+
type: {
|
|
79
|
+
type: "string",
|
|
80
|
+
description: "Type of analysis: command, bundle, file, monorepo, or auto (default: auto)"
|
|
81
|
+
},
|
|
82
|
+
runs: {
|
|
83
|
+
type: "number",
|
|
84
|
+
description: "Number of benchmark iterations (default: 10)"
|
|
85
|
+
},
|
|
86
|
+
warmup: {
|
|
87
|
+
type: "number",
|
|
88
|
+
description: "Warmup runs before measurement (default: 2)"
|
|
89
|
+
},
|
|
90
|
+
concurrency: {
|
|
91
|
+
type: "number",
|
|
92
|
+
description: "For parallel benchmarks (default: 1)"
|
|
93
|
+
},
|
|
94
|
+
compare: {
|
|
95
|
+
type: "boolean",
|
|
96
|
+
description: "Compare with cached baseline (default: false)"
|
|
97
|
+
},
|
|
98
|
+
output: {
|
|
99
|
+
type: "string",
|
|
100
|
+
description: "Output format: console, json, html, or all (default: console)"
|
|
101
|
+
},
|
|
102
|
+
save: {
|
|
103
|
+
type: "boolean",
|
|
104
|
+
description: "Save results as baseline (default: false)"
|
|
105
|
+
},
|
|
106
|
+
verbose: {
|
|
107
|
+
type: "boolean",
|
|
108
|
+
description: "Detailed output (default: false)"
|
|
109
|
+
},
|
|
110
|
+
cwd: {
|
|
111
|
+
type: "string",
|
|
112
|
+
description: "Working directory (default: current directory)"
|
|
113
|
+
},
|
|
114
|
+
ignore: {
|
|
115
|
+
type: "string",
|
|
116
|
+
description: "Packages to ignore for monorepo analysis (supports wildcards like @reliverse/*)"
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
const perfCmdCfg = defineCmdCfg({
|
|
120
|
+
name: "perf",
|
|
121
|
+
description: "Comprehensive performance measurement and analysis tool. Benchmarks commands, analyzes bundles, profiles files/directories, and identifies monorepo bottlenecks.",
|
|
122
|
+
examples: [
|
|
123
|
+
"# Command Benchmarking:",
|
|
124
|
+
"dler perf build",
|
|
125
|
+
'dler perf "bun dler tsc"',
|
|
126
|
+
'dler perf "node --version"',
|
|
127
|
+
"dler perf build --runs 20 --warmup 5",
|
|
128
|
+
"dler perf build --concurrency 4 --verbose",
|
|
129
|
+
"dler perf build --compare --save",
|
|
130
|
+
"",
|
|
131
|
+
"# Bundle Analysis:",
|
|
132
|
+
"dler perf ./dist --type bundle",
|
|
133
|
+
"dler perf ./build --type bundle",
|
|
134
|
+
"dler perf ./dist --type bundle --verbose",
|
|
135
|
+
"",
|
|
136
|
+
"# File System Profiling:",
|
|
137
|
+
"dler perf ./src --type file",
|
|
138
|
+
"dler perf ./packages --type file",
|
|
139
|
+
"dler perf ./src --type file --verbose",
|
|
140
|
+
"",
|
|
141
|
+
"# Monorepo Analysis:",
|
|
142
|
+
"dler perf --type monorepo",
|
|
143
|
+
"dler perf --type monorepo --ignore '@reliverse/*'",
|
|
144
|
+
"dler perf --type monorepo --verbose",
|
|
145
|
+
"",
|
|
146
|
+
"# Auto-detection:",
|
|
147
|
+
"dler perf build # Auto-detects as command",
|
|
148
|
+
"dler perf ./dist # Auto-detects as bundle",
|
|
149
|
+
"dler perf ./src # Auto-detects as file system",
|
|
150
|
+
"dler perf # Auto-detects as monorepo",
|
|
151
|
+
"",
|
|
152
|
+
"# Output Formats:",
|
|
153
|
+
"dler perf build --output json",
|
|
154
|
+
"dler perf build --output html",
|
|
155
|
+
"dler perf build --output all",
|
|
156
|
+
"",
|
|
157
|
+
"# Baseline Comparison:",
|
|
158
|
+
"dler perf build --save # Save current as baseline",
|
|
159
|
+
"dler perf build --compare # Compare with baseline",
|
|
160
|
+
"dler perf build --compare --save # Compare and update baseline",
|
|
161
|
+
"",
|
|
162
|
+
"# Advanced Examples:",
|
|
163
|
+
"dler perf 'bun dler tsc' --runs 50 --warmup 10 --concurrency 2",
|
|
164
|
+
"dler perf ./dist --type bundle --output html --verbose",
|
|
165
|
+
"dler perf --type monorepo --ignore '@reliverse/*' --output json",
|
|
166
|
+
"dler perf build --runs 100 --compare --save --output all",
|
|
167
|
+
"",
|
|
168
|
+
"# Performance Monitoring:",
|
|
169
|
+
"dler perf build --runs 10 --save # Establish baseline",
|
|
170
|
+
"dler perf build --compare # Check for regressions",
|
|
171
|
+
"dler perf build --runs 20 --compare --save # Update baseline",
|
|
172
|
+
"",
|
|
173
|
+
"# Analysis Types:",
|
|
174
|
+
"dler perf --type command <cmd> # Benchmark command execution",
|
|
175
|
+
"dler perf --type bundle <path> # Analyze bundle size and structure",
|
|
176
|
+
"dler perf --type file <path> # Profile file system usage",
|
|
177
|
+
"dler perf --type monorepo # Analyze monorepo dependencies",
|
|
178
|
+
"dler perf --type auto <target> # Auto-detect analysis type",
|
|
179
|
+
"",
|
|
180
|
+
"# Command Examples:",
|
|
181
|
+
"dler perf 'dler build'",
|
|
182
|
+
"dler perf 'bun dler tsc --verbose'",
|
|
183
|
+
"dler perf 'node --version'",
|
|
184
|
+
"dler perf 'npm run build'",
|
|
185
|
+
"dler perf 'yarn test'",
|
|
186
|
+
"",
|
|
187
|
+
"# Bundle Analysis Examples:",
|
|
188
|
+
"dler perf ./dist --type bundle",
|
|
189
|
+
"dler perf ./build --type bundle",
|
|
190
|
+
"dler perf ./out --type bundle",
|
|
191
|
+
"dler perf ./lib --type bundle",
|
|
192
|
+
"",
|
|
193
|
+
"# File System Examples:",
|
|
194
|
+
"dler perf ./src --type file",
|
|
195
|
+
"dler perf ./packages --type file",
|
|
196
|
+
"dler perf ./apps --type file",
|
|
197
|
+
"dler perf ./examples --type file",
|
|
198
|
+
"",
|
|
199
|
+
"# Monorepo Examples:",
|
|
200
|
+
"dler perf --type monorepo",
|
|
201
|
+
"dler perf --type monorepo --cwd /path/to/monorepo",
|
|
202
|
+
"dler perf --type monorepo --ignore '@reliverse/*'",
|
|
203
|
+
"dler perf --type monorepo --ignore '@reliverse/* @company/*'",
|
|
204
|
+
"",
|
|
205
|
+
"# Output Examples:",
|
|
206
|
+
"dler perf build --output console # Console output (default)",
|
|
207
|
+
"dler perf build --output json # JSON output",
|
|
208
|
+
"dler perf build --output html # HTML report",
|
|
209
|
+
"dler perf build --output all # All formats",
|
|
210
|
+
"",
|
|
211
|
+
"# Baseline Management:",
|
|
212
|
+
"dler perf build --save # Save current run as baseline",
|
|
213
|
+
"dler perf build --compare # Compare with saved baseline",
|
|
214
|
+
"dler perf build --compare --save # Compare and update baseline",
|
|
215
|
+
"",
|
|
216
|
+
"# Verbose Output:",
|
|
217
|
+
"dler perf build --verbose # Show detailed progress",
|
|
218
|
+
"dler perf ./dist --type bundle --verbose",
|
|
219
|
+
"dler perf --type monorepo --verbose",
|
|
220
|
+
"",
|
|
221
|
+
"# Concurrency Control:",
|
|
222
|
+
"dler perf build --concurrency 1 # Sequential execution",
|
|
223
|
+
"dler perf build --concurrency 4 # Parallel execution",
|
|
224
|
+
"dler perf build --concurrency 8 # High parallelism",
|
|
225
|
+
"",
|
|
226
|
+
"# Iteration Control:",
|
|
227
|
+
"dler perf build --runs 5 # Few iterations (faster)",
|
|
228
|
+
"dler perf build --runs 50 # Many iterations (more accurate)",
|
|
229
|
+
"dler perf build --warmup 0 # No warmup",
|
|
230
|
+
"dler perf build --warmup 10 # More warmup runs",
|
|
231
|
+
"",
|
|
232
|
+
"# Working Directory:",
|
|
233
|
+
"dler perf build --cwd /path/to/project",
|
|
234
|
+
"dler perf ./dist --type bundle --cwd /path/to/project",
|
|
235
|
+
"dler perf --type monorepo --cwd /path/to/monorepo"
|
|
236
|
+
]
|
|
237
|
+
});
|
|
238
|
+
export default defineCmd(perfCmd, perfCmdArgs, perfCmdCfg);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { PerfOptions, PerfReport } from "./types.js";
|
|
2
|
+
export interface PerfAnalysisResult {
|
|
3
|
+
report: PerfReport;
|
|
4
|
+
success: boolean;
|
|
5
|
+
error?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class PerfAnalyzer {
|
|
8
|
+
private options;
|
|
9
|
+
private cache;
|
|
10
|
+
constructor(options: PerfOptions);
|
|
11
|
+
analyze(): Promise<PerfAnalysisResult>;
|
|
12
|
+
private detectType;
|
|
13
|
+
private detectTargetType;
|
|
14
|
+
private isCommand;
|
|
15
|
+
private isBundleFile;
|
|
16
|
+
private containsBundleFiles;
|
|
17
|
+
private runCommandBenchmark;
|
|
18
|
+
private runBundleAnalysis;
|
|
19
|
+
private runFileSystemAnalysis;
|
|
20
|
+
private runMonorepoAnalysis;
|
|
21
|
+
private compareWithBaseline;
|
|
22
|
+
}
|
|
23
|
+
export declare const runPerfAnalysis: (options: PerfOptions) => Promise<PerfAnalysisResult>;
|
|
24
|
+
export declare const createPerfAnalyzer: (options: PerfOptions) => PerfAnalyzer;
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { existsSync, statSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { logger } from "@reliverse/dler-logger";
|
|
4
|
+
import { analyzeBundle } from "./analysis/bundle.js";
|
|
5
|
+
import { analyzeFileSystem } from "./analysis/filesystem.js";
|
|
6
|
+
import { analyzeMonorepo } from "./analysis/monorepo.js";
|
|
7
|
+
import { runBenchmark } from "./benchmarks/runner.js";
|
|
8
|
+
import { createPerfCache } from "./utils/cache.js";
|
|
9
|
+
import { calculateImprovement, calculateRegression } from "./utils/stats.js";
|
|
10
|
+
export class PerfAnalyzer {
|
|
11
|
+
options;
|
|
12
|
+
cache = createPerfCache();
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
}
|
|
16
|
+
async analyze() {
|
|
17
|
+
try {
|
|
18
|
+
const startTime = Date.now();
|
|
19
|
+
const analysisType = this.options.type ?? await this.detectType();
|
|
20
|
+
if (this.options.verbose) {
|
|
21
|
+
logger.info(`\u{1F50D} Starting performance analysis (type: ${analysisType})`);
|
|
22
|
+
}
|
|
23
|
+
let benchmark;
|
|
24
|
+
let bundleAnalysis;
|
|
25
|
+
let fileSystemAnalysis;
|
|
26
|
+
let monorepoAnalysis;
|
|
27
|
+
switch (analysisType) {
|
|
28
|
+
case "command":
|
|
29
|
+
benchmark = await this.runCommandBenchmark();
|
|
30
|
+
break;
|
|
31
|
+
case "bundle":
|
|
32
|
+
bundleAnalysis = await this.runBundleAnalysis();
|
|
33
|
+
break;
|
|
34
|
+
case "file":
|
|
35
|
+
fileSystemAnalysis = await this.runFileSystemAnalysis();
|
|
36
|
+
break;
|
|
37
|
+
case "monorepo":
|
|
38
|
+
monorepoAnalysis = await this.runMonorepoAnalysis();
|
|
39
|
+
break;
|
|
40
|
+
case "auto":
|
|
41
|
+
if (this.options.target) {
|
|
42
|
+
const targetType = await this.detectTargetType(this.options.target);
|
|
43
|
+
switch (targetType) {
|
|
44
|
+
case "command":
|
|
45
|
+
benchmark = await this.runCommandBenchmark();
|
|
46
|
+
break;
|
|
47
|
+
case "bundle":
|
|
48
|
+
bundleAnalysis = await this.runBundleAnalysis();
|
|
49
|
+
break;
|
|
50
|
+
case "file":
|
|
51
|
+
fileSystemAnalysis = await this.runFileSystemAnalysis();
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
monorepoAnalysis = await this.runMonorepoAnalysis();
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
const report = {
|
|
60
|
+
timestamp: Date.now(),
|
|
61
|
+
options: this.options,
|
|
62
|
+
benchmark,
|
|
63
|
+
bundleAnalysis,
|
|
64
|
+
fileSystemAnalysis,
|
|
65
|
+
monorepoAnalysis
|
|
66
|
+
};
|
|
67
|
+
if (this.options.compare) {
|
|
68
|
+
const baseline = await this.cache.findBaseline(
|
|
69
|
+
this.options.target ?? "unknown",
|
|
70
|
+
this.options.type
|
|
71
|
+
);
|
|
72
|
+
if (baseline) {
|
|
73
|
+
report.baseline = this.compareWithBaseline(report, baseline);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (this.options.save) {
|
|
77
|
+
await this.cache.save(report);
|
|
78
|
+
if (this.options.verbose) {
|
|
79
|
+
logger.info("\u{1F4BE} Baseline saved");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const executionTime = Date.now() - startTime;
|
|
83
|
+
if (this.options.verbose) {
|
|
84
|
+
logger.info(`\u2705 Analysis completed in ${executionTime}ms`);
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
report,
|
|
88
|
+
success: true
|
|
89
|
+
};
|
|
90
|
+
} catch (error) {
|
|
91
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
92
|
+
if (this.options.verbose) {
|
|
93
|
+
logger.error(`\u274C Analysis failed: ${errorMessage}`);
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
report: {
|
|
97
|
+
timestamp: Date.now(),
|
|
98
|
+
options: this.options
|
|
99
|
+
},
|
|
100
|
+
success: false,
|
|
101
|
+
error: errorMessage
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async detectType() {
|
|
106
|
+
if (this.options.target) {
|
|
107
|
+
return await this.detectTargetType(this.options.target);
|
|
108
|
+
}
|
|
109
|
+
return "monorepo";
|
|
110
|
+
}
|
|
111
|
+
async detectTargetType(target) {
|
|
112
|
+
if (this.isCommand(target)) {
|
|
113
|
+
return "command";
|
|
114
|
+
}
|
|
115
|
+
const targetPath = resolve(target);
|
|
116
|
+
if (!existsSync(targetPath)) {
|
|
117
|
+
throw new Error(`Target not found: ${target}`);
|
|
118
|
+
}
|
|
119
|
+
const stat = statSync(targetPath);
|
|
120
|
+
if (stat.isFile()) {
|
|
121
|
+
if (this.isBundleFile(target)) {
|
|
122
|
+
return "bundle";
|
|
123
|
+
}
|
|
124
|
+
return "file";
|
|
125
|
+
}
|
|
126
|
+
if (stat.isDirectory()) {
|
|
127
|
+
if (await this.containsBundleFiles(targetPath)) {
|
|
128
|
+
return "bundle";
|
|
129
|
+
}
|
|
130
|
+
return "file";
|
|
131
|
+
}
|
|
132
|
+
return "file";
|
|
133
|
+
}
|
|
134
|
+
isCommand(target) {
|
|
135
|
+
return target.includes(" ") || target.startsWith("dler ") || target.startsWith("bun ") || target.startsWith("node ") || target.startsWith("npm ") || target.startsWith("yarn ") || target.startsWith("pnpm ");
|
|
136
|
+
}
|
|
137
|
+
isBundleFile(target) {
|
|
138
|
+
const bundleExtensions = [".js", ".mjs", ".cjs", ".ts", ".jsx", ".tsx"];
|
|
139
|
+
const ext = target.split(".").pop()?.toLowerCase();
|
|
140
|
+
return ext ? bundleExtensions.includes(`.${ext}`) : false;
|
|
141
|
+
}
|
|
142
|
+
async containsBundleFiles(dirPath) {
|
|
143
|
+
try {
|
|
144
|
+
const glob = new Bun.Glob("**/*.{js,mjs,cjs,ts,jsx,tsx}");
|
|
145
|
+
const matches = glob.scanSync({ cwd: dirPath, onlyFiles: true });
|
|
146
|
+
for (const _ of matches) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
return false;
|
|
150
|
+
} catch {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
async runCommandBenchmark() {
|
|
155
|
+
if (!this.options.target) {
|
|
156
|
+
throw new Error("Target is required for command benchmarking");
|
|
157
|
+
}
|
|
158
|
+
const {
|
|
159
|
+
target,
|
|
160
|
+
runs = 10,
|
|
161
|
+
warmup = 2,
|
|
162
|
+
concurrency = 1,
|
|
163
|
+
cwd,
|
|
164
|
+
verbose
|
|
165
|
+
} = this.options;
|
|
166
|
+
if (verbose) {
|
|
167
|
+
logger.info(`\u{1F680} Benchmarking command: ${target}`);
|
|
168
|
+
}
|
|
169
|
+
return runBenchmark({
|
|
170
|
+
command: target,
|
|
171
|
+
runs,
|
|
172
|
+
warmup,
|
|
173
|
+
concurrency,
|
|
174
|
+
cwd,
|
|
175
|
+
verbose
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
async runBundleAnalysis() {
|
|
179
|
+
if (!this.options.target) {
|
|
180
|
+
throw new Error("Target is required for bundle analysis");
|
|
181
|
+
}
|
|
182
|
+
const { target, verbose } = this.options;
|
|
183
|
+
if (verbose) {
|
|
184
|
+
logger.info(`\u{1F4E6} Analyzing bundle: ${target}`);
|
|
185
|
+
}
|
|
186
|
+
return analyzeBundle({
|
|
187
|
+
target,
|
|
188
|
+
verbose,
|
|
189
|
+
includeSourceMaps: true,
|
|
190
|
+
analyzeDependencies: true
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
async runFileSystemAnalysis() {
|
|
194
|
+
if (!this.options.target) {
|
|
195
|
+
throw new Error("Target is required for file system analysis");
|
|
196
|
+
}
|
|
197
|
+
const { target, verbose } = this.options;
|
|
198
|
+
if (verbose) {
|
|
199
|
+
logger.info(`\u{1F4C1} Analyzing file system: ${target}`);
|
|
200
|
+
}
|
|
201
|
+
return analyzeFileSystem({
|
|
202
|
+
target,
|
|
203
|
+
verbose,
|
|
204
|
+
maxDepth: 10,
|
|
205
|
+
includeHidden: false,
|
|
206
|
+
excludePatterns: [
|
|
207
|
+
"node_modules",
|
|
208
|
+
".git",
|
|
209
|
+
".next",
|
|
210
|
+
".nuxt",
|
|
211
|
+
"dist",
|
|
212
|
+
"build"
|
|
213
|
+
]
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
async runMonorepoAnalysis() {
|
|
217
|
+
const { cwd, ignore, verbose } = this.options;
|
|
218
|
+
if (verbose) {
|
|
219
|
+
logger.info("\u{1F3D7}\uFE0F Analyzing monorepo structure");
|
|
220
|
+
}
|
|
221
|
+
return analyzeMonorepo({
|
|
222
|
+
cwd,
|
|
223
|
+
ignore,
|
|
224
|
+
verbose,
|
|
225
|
+
includeDevDependencies: true,
|
|
226
|
+
analyzeBuildOrder: true
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
compareWithBaseline(current, baseline) {
|
|
230
|
+
const changes = {};
|
|
231
|
+
if (current.benchmark && baseline.benchmark) {
|
|
232
|
+
const currentDuration = current.benchmark.statistics.mean;
|
|
233
|
+
const baselineDuration = baseline.benchmark.statistics.mean;
|
|
234
|
+
if (currentDuration < baselineDuration) {
|
|
235
|
+
changes.duration = calculateImprovement(
|
|
236
|
+
baselineDuration,
|
|
237
|
+
currentDuration
|
|
238
|
+
);
|
|
239
|
+
} else {
|
|
240
|
+
changes.duration = calculateRegression(
|
|
241
|
+
baselineDuration,
|
|
242
|
+
currentDuration
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
const currentMemory = current.benchmark.memory.average.rss;
|
|
246
|
+
const baselineMemory = baseline.benchmark.memory.average.rss;
|
|
247
|
+
if (currentMemory < baselineMemory) {
|
|
248
|
+
changes.memory = calculateImprovement(baselineMemory, currentMemory);
|
|
249
|
+
} else {
|
|
250
|
+
changes.memory = calculateRegression(baselineMemory, currentMemory);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (current.bundleAnalysis && baseline.bundleAnalysis) {
|
|
254
|
+
const currentSize = current.bundleAnalysis.totalSize;
|
|
255
|
+
const baselineSize = baseline.bundleAnalysis.totalSize;
|
|
256
|
+
if (currentSize < baselineSize) {
|
|
257
|
+
changes.size = calculateImprovement(baselineSize, currentSize);
|
|
258
|
+
} else {
|
|
259
|
+
changes.size = calculateRegression(baselineSize, currentSize);
|
|
260
|
+
}
|
|
261
|
+
const currentFiles = current.bundleAnalysis.fileCount;
|
|
262
|
+
const baselineFiles = baseline.bundleAnalysis.fileCount;
|
|
263
|
+
if (currentFiles !== baselineFiles) {
|
|
264
|
+
changes.files = calculateRegression(baselineFiles, currentFiles);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (current.fileSystemAnalysis && baseline.fileSystemAnalysis) {
|
|
268
|
+
const currentSize = current.fileSystemAnalysis.totalSize;
|
|
269
|
+
const baselineSize = baseline.fileSystemAnalysis.totalSize;
|
|
270
|
+
if (currentSize < baselineSize) {
|
|
271
|
+
changes.size = calculateImprovement(baselineSize, currentSize);
|
|
272
|
+
} else {
|
|
273
|
+
changes.size = calculateRegression(baselineSize, currentSize);
|
|
274
|
+
}
|
|
275
|
+
const currentFiles = current.fileSystemAnalysis.totalFiles;
|
|
276
|
+
const baselineFiles = baseline.fileSystemAnalysis.totalFiles;
|
|
277
|
+
if (currentFiles !== baselineFiles) {
|
|
278
|
+
changes.files = calculateRegression(baselineFiles, currentFiles);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
let improvement;
|
|
282
|
+
let regression;
|
|
283
|
+
if (changes.duration !== void 0) {
|
|
284
|
+
if (changes.duration > 0) {
|
|
285
|
+
improvement = changes.duration;
|
|
286
|
+
} else {
|
|
287
|
+
regression = Math.abs(changes.duration);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return {
|
|
291
|
+
exists: true,
|
|
292
|
+
improvement,
|
|
293
|
+
regression,
|
|
294
|
+
changes
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
export const runPerfAnalysis = async (options) => {
|
|
299
|
+
const analyzer = new PerfAnalyzer(options);
|
|
300
|
+
return analyzer.analyze();
|
|
301
|
+
};
|
|
302
|
+
export const createPerfAnalyzer = (options) => {
|
|
303
|
+
return new PerfAnalyzer(options);
|
|
304
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PerfReport } from "../types.js";
|
|
2
|
+
export declare class ConsoleReporter {
|
|
3
|
+
private verbose;
|
|
4
|
+
constructor(verbose?: boolean);
|
|
5
|
+
report(report: PerfReport): void;
|
|
6
|
+
private reportBenchmark;
|
|
7
|
+
private reportBundleAnalysis;
|
|
8
|
+
private reportFileSystemAnalysis;
|
|
9
|
+
private reportMonorepoAnalysis;
|
|
10
|
+
private reportBaselineComparison;
|
|
11
|
+
}
|
|
12
|
+
export declare const createConsoleReporter: (verbose?: boolean) => ConsoleReporter;
|