@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.
Files changed (135) hide show
  1. package/dist/cli.d.ts +2 -0
  2. package/dist/cli.js +3 -0
  3. package/dist/cmds/build/cmd.d.ts +2 -0
  4. package/dist/cmds/build/cmd.js +564 -0
  5. package/dist/cmds/clean/cmd.d.ts +2 -0
  6. package/dist/cmds/clean/cmd.js +146 -0
  7. package/dist/cmds/clean/impl.d.ts +2 -0
  8. package/dist/cmds/clean/impl.js +627 -0
  9. package/dist/cmds/clean/presets.d.ts +10 -0
  10. package/dist/cmds/clean/presets.js +112 -0
  11. package/dist/cmds/clean/types.d.ts +62 -0
  12. package/dist/cmds/clean/types.js +0 -0
  13. package/dist/cmds/init/cmd.d.ts +3 -0
  14. package/dist/cmds/init/cmd.js +56 -0
  15. package/dist/cmds/init/impl/config.d.ts +45 -0
  16. package/dist/cmds/init/impl/config.js +99 -0
  17. package/dist/cmds/init/impl/generators.d.ts +6 -0
  18. package/dist/cmds/init/impl/generators.js +178 -0
  19. package/dist/cmds/init/impl/prompts.d.ts +2 -0
  20. package/dist/cmds/init/impl/prompts.js +98 -0
  21. package/dist/cmds/init/impl/types.d.ts +22 -0
  22. package/dist/cmds/init/impl/types.js +0 -0
  23. package/dist/cmds/init/impl/utils.d.ts +4 -0
  24. package/dist/cmds/init/impl/utils.js +11 -0
  25. package/dist/cmds/init/impl/validators.d.ts +4 -0
  26. package/dist/cmds/init/impl/validators.js +42 -0
  27. package/dist/cmds/integrate/cmd.d.ts +3 -0
  28. package/dist/cmds/integrate/cmd.js +70 -0
  29. package/dist/cmds/integrate/impl.d.ts +7 -0
  30. package/dist/cmds/integrate/impl.js +127 -0
  31. package/dist/cmds/integrate/integrations/base.d.ts +13 -0
  32. package/dist/cmds/integrate/integrations/base.js +41 -0
  33. package/dist/cmds/integrate/integrations/nextjs.d.ts +16 -0
  34. package/dist/cmds/integrate/integrations/nextjs.js +167 -0
  35. package/dist/cmds/integrate/integrations/registry.d.ts +7 -0
  36. package/dist/cmds/integrate/integrations/registry.js +31 -0
  37. package/dist/cmds/integrate/integrations/ultracite.d.ts +11 -0
  38. package/dist/cmds/integrate/integrations/ultracite.js +40 -0
  39. package/dist/cmds/integrate/types.d.ts +39 -0
  40. package/dist/cmds/integrate/types.js +0 -0
  41. package/dist/cmds/integrate/utils/biome.d.ts +4 -0
  42. package/dist/cmds/integrate/utils/biome.js +140 -0
  43. package/dist/cmds/integrate/utils/context.d.ts +3 -0
  44. package/dist/cmds/integrate/utils/context.js +111 -0
  45. package/dist/cmds/integrate/utils/temp.d.ts +3 -0
  46. package/dist/cmds/integrate/utils/temp.js +36 -0
  47. package/dist/cmds/perf/analysis/bundle.d.ts +20 -0
  48. package/dist/cmds/perf/analysis/bundle.js +225 -0
  49. package/dist/cmds/perf/analysis/filesystem.d.ts +27 -0
  50. package/dist/cmds/perf/analysis/filesystem.js +246 -0
  51. package/dist/cmds/perf/analysis/monorepo.d.ts +29 -0
  52. package/dist/cmds/perf/analysis/monorepo.js +307 -0
  53. package/dist/cmds/perf/benchmarks/command.d.ts +21 -0
  54. package/dist/cmds/perf/benchmarks/command.js +162 -0
  55. package/dist/cmds/perf/benchmarks/memory.d.ts +41 -0
  56. package/dist/cmds/perf/benchmarks/memory.js +169 -0
  57. package/dist/cmds/perf/benchmarks/runner.d.ts +22 -0
  58. package/dist/cmds/perf/benchmarks/runner.js +157 -0
  59. package/dist/cmds/perf/cmd.d.ts +2 -0
  60. package/dist/cmds/perf/cmd.js +238 -0
  61. package/dist/cmds/perf/impl.d.ts +24 -0
  62. package/dist/cmds/perf/impl.js +304 -0
  63. package/dist/cmds/perf/reporters/console.d.ts +12 -0
  64. package/dist/cmds/perf/reporters/console.js +257 -0
  65. package/dist/cmds/perf/reporters/html.d.ts +27 -0
  66. package/dist/cmds/perf/reporters/html.js +881 -0
  67. package/dist/cmds/perf/reporters/json.d.ts +9 -0
  68. package/dist/cmds/perf/reporters/json.js +32 -0
  69. package/dist/cmds/perf/types.d.ts +184 -0
  70. package/dist/cmds/perf/types.js +0 -0
  71. package/dist/cmds/perf/utils/cache.d.ts +23 -0
  72. package/dist/cmds/perf/utils/cache.js +171 -0
  73. package/dist/cmds/perf/utils/formatter.d.ts +17 -0
  74. package/dist/cmds/perf/utils/formatter.js +134 -0
  75. package/dist/cmds/perf/utils/stats.d.ts +15 -0
  76. package/dist/cmds/perf/utils/stats.js +101 -0
  77. package/dist/cmds/publish/cmd.d.ts +3 -0
  78. package/dist/cmds/publish/cmd.js +189 -0
  79. package/dist/cmds/shell/cmd.d.ts +3 -0
  80. package/dist/cmds/shell/cmd.js +50 -0
  81. package/dist/cmds/tsc/cache.d.ts +27 -0
  82. package/dist/cmds/tsc/cache.js +160 -0
  83. package/dist/cmds/tsc/cmd.d.ts +2 -0
  84. package/dist/cmds/tsc/cmd.js +111 -0
  85. package/dist/cmds/tsc/impl.d.ts +41 -0
  86. package/dist/cmds/tsc/impl.js +572 -0
  87. package/dist/cmds/tsc/types.d.ts +57 -0
  88. package/dist/cmds/tsc/types.js +0 -0
  89. package/package.json +4 -11
  90. package/src/cli.ts +8 -0
  91. package/src/cmds/build/cmd.ts +582 -0
  92. package/src/cmds/clean/cmd.ts +166 -0
  93. package/src/cmds/clean/impl.ts +900 -0
  94. package/src/cmds/clean/presets.ts +158 -0
  95. package/src/cmds/clean/types.ts +71 -0
  96. package/src/cmds/init/cmd.ts +68 -0
  97. package/src/cmds/init/impl/config.ts +105 -0
  98. package/src/cmds/init/impl/generators.ts +220 -0
  99. package/src/cmds/init/impl/prompts.ts +137 -0
  100. package/src/cmds/init/impl/types.ts +25 -0
  101. package/src/cmds/init/impl/utils.ts +17 -0
  102. package/src/cmds/init/impl/validators.ts +55 -0
  103. package/src/cmds/integrate/cmd.ts +82 -0
  104. package/src/cmds/integrate/impl.ts +204 -0
  105. package/src/cmds/integrate/integrations/base.ts +69 -0
  106. package/src/cmds/integrate/integrations/nextjs.ts +227 -0
  107. package/src/cmds/integrate/integrations/registry.ts +45 -0
  108. package/src/cmds/integrate/integrations/ultracite.ts +53 -0
  109. package/src/cmds/integrate/types.ts +48 -0
  110. package/src/cmds/integrate/utils/biome.ts +173 -0
  111. package/src/cmds/integrate/utils/context.ts +148 -0
  112. package/src/cmds/integrate/utils/temp.ts +47 -0
  113. package/src/cmds/perf/analysis/bundle.ts +311 -0
  114. package/src/cmds/perf/analysis/filesystem.ts +324 -0
  115. package/src/cmds/perf/analysis/monorepo.ts +439 -0
  116. package/src/cmds/perf/benchmarks/command.ts +230 -0
  117. package/src/cmds/perf/benchmarks/memory.ts +249 -0
  118. package/src/cmds/perf/benchmarks/runner.ts +220 -0
  119. package/src/cmds/perf/cmd.ts +285 -0
  120. package/src/cmds/perf/impl.ts +411 -0
  121. package/src/cmds/perf/reporters/console.ts +331 -0
  122. package/src/cmds/perf/reporters/html.ts +984 -0
  123. package/src/cmds/perf/reporters/json.ts +42 -0
  124. package/src/cmds/perf/types.ts +220 -0
  125. package/src/cmds/perf/utils/cache.ts +234 -0
  126. package/src/cmds/perf/utils/formatter.ts +190 -0
  127. package/src/cmds/perf/utils/stats.ts +153 -0
  128. package/src/cmds/publish/cmd.ts +215 -0
  129. package/src/cmds/shell/cmd.ts +61 -0
  130. package/src/cmds/tsc/cache.ts +237 -0
  131. package/src/cmds/tsc/cmd.ts +139 -0
  132. package/src/cmds/tsc/impl.ts +855 -0
  133. package/src/cmds/tsc/types.ts +66 -0
  134. package/tsconfig.json +9 -0
  135. package/cli.js +0 -1316
@@ -0,0 +1,162 @@
1
+ import { existsSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { lookpath } from "lookpath";
4
+ export const executeCommand = async (command, options = {}) => {
5
+ const startTime = process.hrtime.bigint();
6
+ try {
7
+ const [cmd, ...args] = parseCommand(command);
8
+ if (!cmd) {
9
+ throw new Error("Command is empty");
10
+ }
11
+ const commandPath = await findCommand(cmd);
12
+ if (!commandPath) {
13
+ throw new Error(`Command not found: ${cmd}`);
14
+ }
15
+ const proc = Bun.spawn([commandPath, ...args], {
16
+ cwd: options.cwd ?? process.cwd(),
17
+ env: { ...process.env, ...options.env },
18
+ stdout: "pipe",
19
+ stderr: "pipe"
20
+ });
21
+ let timeoutId;
22
+ if (options.timeout) {
23
+ timeoutId = setTimeout(() => {
24
+ proc.kill();
25
+ }, options.timeout);
26
+ }
27
+ const [stdout, stderr] = await Promise.all([
28
+ new Response(proc.stdout).text(),
29
+ new Response(proc.stderr).text()
30
+ ]);
31
+ const exitCode = await proc.exited;
32
+ const endTime = process.hrtime.bigint();
33
+ const endMemory = process.memoryUsage();
34
+ if (timeoutId) {
35
+ clearTimeout(timeoutId);
36
+ }
37
+ const duration = Number(endTime - startTime) / 1e6;
38
+ return {
39
+ success: exitCode === 0,
40
+ duration,
41
+ memory: {
42
+ rss: endMemory.rss,
43
+ heapTotal: endMemory.heapTotal,
44
+ heapUsed: endMemory.heapUsed,
45
+ external: endMemory.external,
46
+ arrayBuffers: endMemory.arrayBuffers
47
+ },
48
+ stdout,
49
+ stderr,
50
+ exitCode
51
+ };
52
+ } catch (error) {
53
+ const endTime = process.hrtime.bigint();
54
+ const endMemory = process.memoryUsage();
55
+ const duration = Number(endTime - startTime) / 1e6;
56
+ return {
57
+ success: false,
58
+ duration,
59
+ memory: {
60
+ rss: endMemory.rss,
61
+ heapTotal: endMemory.heapTotal,
62
+ heapUsed: endMemory.heapUsed,
63
+ external: endMemory.external,
64
+ arrayBuffers: endMemory.arrayBuffers
65
+ },
66
+ stdout: "",
67
+ stderr: "",
68
+ error: error instanceof Error ? error.message : String(error),
69
+ exitCode: 1
70
+ };
71
+ }
72
+ };
73
+ export const executeCommandWithMemoryTracking = async (command, options = {}) => {
74
+ const result = await executeCommand(command, options);
75
+ const endMemory = process.memoryUsage();
76
+ return {
77
+ run: 0,
78
+ // Will be set by the runner
79
+ duration: result.duration,
80
+ memory: {
81
+ rss: endMemory.rss,
82
+ heapTotal: endMemory.heapTotal,
83
+ heapUsed: endMemory.heapUsed,
84
+ external: endMemory.external,
85
+ arrayBuffers: endMemory.arrayBuffers
86
+ },
87
+ success: result.success,
88
+ error: result.error,
89
+ stdout: result.stdout,
90
+ stderr: result.stderr
91
+ };
92
+ };
93
+ const parseCommand = (command) => {
94
+ const parts = [];
95
+ let current = "";
96
+ let inQuotes = false;
97
+ let quoteChar = "";
98
+ for (let i = 0; i < command.length; i++) {
99
+ const char = command[i];
100
+ if (char === '"' || char === "'") {
101
+ if (!inQuotes) {
102
+ inQuotes = true;
103
+ quoteChar = char;
104
+ } else if (char === quoteChar) {
105
+ inQuotes = false;
106
+ quoteChar = "";
107
+ } else {
108
+ current += char;
109
+ }
110
+ } else if (char === " " && !inQuotes) {
111
+ if (current.trim()) {
112
+ parts.push(current.trim());
113
+ current = "";
114
+ }
115
+ } else {
116
+ current += char;
117
+ }
118
+ }
119
+ if (current.trim()) {
120
+ parts.push(current.trim());
121
+ }
122
+ return parts;
123
+ };
124
+ const findCommand = async (cmd) => {
125
+ if (!cmd) {
126
+ return null;
127
+ }
128
+ if (cmd === "dler") {
129
+ return "bun";
130
+ }
131
+ if (cmd === "bun") {
132
+ return "bun";
133
+ }
134
+ if (cmd === "node") {
135
+ return "node";
136
+ }
137
+ if (cmd.includes("/") || cmd.includes("\\")) {
138
+ const fullPath = resolve(cmd);
139
+ return existsSync(fullPath) ? fullPath : null;
140
+ }
141
+ try {
142
+ const path = await lookpath(cmd);
143
+ return path ?? null;
144
+ } catch {
145
+ return null;
146
+ }
147
+ };
148
+ export const isDlerCommand = (command) => {
149
+ return command.startsWith("dler ") || command === "dler";
150
+ };
151
+ export const isBunCommand = (command) => {
152
+ return command.startsWith("bun ") || command === "bun";
153
+ };
154
+ export const isNodeCommand = (command) => {
155
+ return command.startsWith("node ") || command === "node";
156
+ };
157
+ export const getCommandType = (command) => {
158
+ if (isDlerCommand(command)) return "dler";
159
+ if (isBunCommand(command)) return "bun";
160
+ if (isNodeCommand(command)) return "node";
161
+ return "external";
162
+ };
@@ -0,0 +1,41 @@
1
+ import type { MemoryUsage } from "../types.js";
2
+ export interface MemoryProfile {
3
+ timestamp: number;
4
+ memory: MemoryUsage;
5
+ label?: string;
6
+ }
7
+ export interface MemorySnapshot {
8
+ before: MemoryUsage;
9
+ after: MemoryUsage;
10
+ peak: MemoryUsage;
11
+ growth: number;
12
+ duration: number;
13
+ }
14
+ export declare class MemoryProfiler {
15
+ private snapshots;
16
+ private startMemory;
17
+ private peakMemory;
18
+ start(label?: string): void;
19
+ snapshot(label?: string): void;
20
+ stop(): MemorySnapshot | null;
21
+ getSnapshots(): MemoryProfile[];
22
+ getMemoryGrowth(): number;
23
+ getPeakMemory(): MemoryUsage | null;
24
+ getAverageMemory(): MemoryUsage | null;
25
+ }
26
+ export declare const createMemoryProfiler: () => MemoryProfiler;
27
+ export declare const measureMemoryUsage: (fn: () => void | Promise<void>) => Promise<MemorySnapshot>;
28
+ export declare const getCurrentMemoryUsage: () => MemoryUsage;
29
+ export declare const getMemoryInfo: () => {
30
+ total: number;
31
+ free: number;
32
+ used: number;
33
+ percentage: number;
34
+ };
35
+ export declare const formatMemoryUsage: (usage: MemoryUsage) => string;
36
+ export declare const detectMemoryLeaks: (snapshots: MemoryProfile[]) => {
37
+ hasLeak: boolean;
38
+ severity: "low" | "medium" | "high";
39
+ growthRate: number;
40
+ suggestion: string;
41
+ };
@@ -0,0 +1,169 @@
1
+ export class MemoryProfiler {
2
+ snapshots = [];
3
+ startMemory = null;
4
+ peakMemory = null;
5
+ start(label) {
6
+ this.startMemory = process.memoryUsage();
7
+ this.peakMemory = { ...this.startMemory };
8
+ this.snapshots.push({
9
+ timestamp: Date.now(),
10
+ memory: this.startMemory,
11
+ label: label ?? "start"
12
+ });
13
+ }
14
+ snapshot(label) {
15
+ const current = process.memoryUsage();
16
+ this.snapshots.push({
17
+ timestamp: Date.now(),
18
+ memory: current,
19
+ label: label ?? `snapshot-${this.snapshots.length}`
20
+ });
21
+ if (!this.peakMemory) {
22
+ this.peakMemory = { ...current };
23
+ } else {
24
+ this.peakMemory = {
25
+ rss: Math.max(this.peakMemory.rss, current.rss),
26
+ heapTotal: Math.max(this.peakMemory.heapTotal, current.heapTotal),
27
+ heapUsed: Math.max(this.peakMemory.heapUsed, current.heapUsed),
28
+ external: Math.max(this.peakMemory.external, current.external),
29
+ arrayBuffers: Math.max(
30
+ this.peakMemory.arrayBuffers,
31
+ current.arrayBuffers
32
+ )
33
+ };
34
+ }
35
+ }
36
+ stop() {
37
+ if (!this.startMemory) {
38
+ return null;
39
+ }
40
+ const endMemory = process.memoryUsage();
41
+ const duration = this.snapshots.length > 0 ? this.snapshots[this.snapshots.length - 1].timestamp - this.snapshots[0].timestamp : 0;
42
+ const snapshot = {
43
+ before: this.startMemory,
44
+ after: endMemory,
45
+ peak: this.peakMemory ?? endMemory,
46
+ growth: endMemory.rss - this.startMemory.rss,
47
+ duration
48
+ };
49
+ this.startMemory = null;
50
+ this.peakMemory = null;
51
+ this.snapshots = [];
52
+ return snapshot;
53
+ }
54
+ getSnapshots() {
55
+ return [...this.snapshots];
56
+ }
57
+ getMemoryGrowth() {
58
+ if (this.snapshots.length < 2) return 0;
59
+ const first = this.snapshots[0].memory;
60
+ const last = this.snapshots[this.snapshots.length - 1].memory;
61
+ return last.rss - first.rss;
62
+ }
63
+ getPeakMemory() {
64
+ return this.peakMemory;
65
+ }
66
+ getAverageMemory() {
67
+ if (this.snapshots.length === 0) return null;
68
+ const sum = this.snapshots.reduce(
69
+ (acc, snapshot) => ({
70
+ rss: acc.rss + snapshot.memory.rss,
71
+ heapTotal: acc.heapTotal + snapshot.memory.heapTotal,
72
+ heapUsed: acc.heapUsed + snapshot.memory.heapUsed,
73
+ external: acc.external + snapshot.memory.external,
74
+ arrayBuffers: acc.arrayBuffers + snapshot.memory.arrayBuffers
75
+ }),
76
+ { rss: 0, heapTotal: 0, heapUsed: 0, external: 0, arrayBuffers: 0 }
77
+ );
78
+ const count = this.snapshots.length;
79
+ return {
80
+ rss: sum.rss / count,
81
+ heapTotal: sum.heapTotal / count,
82
+ heapUsed: sum.heapUsed / count,
83
+ external: sum.external / count,
84
+ arrayBuffers: sum.arrayBuffers / count
85
+ };
86
+ }
87
+ }
88
+ export const createMemoryProfiler = () => {
89
+ return new MemoryProfiler();
90
+ };
91
+ export const measureMemoryUsage = (fn) => {
92
+ return new Promise((resolve) => {
93
+ const profiler = createMemoryProfiler();
94
+ profiler.start("measurement");
95
+ const executeFn = async () => {
96
+ try {
97
+ await fn();
98
+ } finally {
99
+ const snapshot = profiler.stop();
100
+ resolve(snapshot);
101
+ }
102
+ };
103
+ executeFn();
104
+ });
105
+ };
106
+ export const getCurrentMemoryUsage = () => {
107
+ return process.memoryUsage();
108
+ };
109
+ export const getMemoryInfo = () => {
110
+ const usage = process.memoryUsage();
111
+ const total = usage.rss * 4;
112
+ const used = usage.rss;
113
+ const free = total - used;
114
+ const percentage = used / total * 100;
115
+ return {
116
+ total,
117
+ free,
118
+ used,
119
+ percentage: Math.min(percentage, 100)
120
+ };
121
+ };
122
+ export const formatMemoryUsage = (usage) => {
123
+ const format = (bytes) => {
124
+ if (bytes === 0) return "0 B";
125
+ const k = 1024;
126
+ const sizes = ["B", "KB", "MB", "GB"];
127
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
128
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
129
+ };
130
+ return `RSS: ${format(usage.rss)}, Heap: ${format(usage.heapUsed)}/${format(usage.heapTotal)}, External: ${format(usage.external)}`;
131
+ };
132
+ export const detectMemoryLeaks = (snapshots) => {
133
+ if (snapshots.length < 3) {
134
+ return {
135
+ hasLeak: false,
136
+ severity: "low",
137
+ growthRate: 0,
138
+ suggestion: "Need more snapshots to detect leaks"
139
+ };
140
+ }
141
+ const rssValues = snapshots.map((s) => s.memory.rss);
142
+ const growthRate = (rssValues[rssValues.length - 1] - rssValues[0]) / snapshots.length;
143
+ const isConsistentGrowth = rssValues.every(
144
+ (val, i) => i === 0 || val >= rssValues[i - 1] * 0.95
145
+ );
146
+ const hasLeak = isConsistentGrowth && growthRate > 1024 * 1024;
147
+ let severity = "low";
148
+ let suggestion = "";
149
+ if (hasLeak) {
150
+ if (growthRate > 10 * 1024 * 1024) {
151
+ severity = "high";
152
+ suggestion = "Critical memory leak detected. Check for unclosed resources, event listeners, or circular references.";
153
+ } else if (growthRate > 5 * 1024 * 1024) {
154
+ severity = "medium";
155
+ suggestion = "Moderate memory leak detected. Monitor memory usage and consider garbage collection.";
156
+ } else {
157
+ severity = "low";
158
+ suggestion = "Minor memory growth detected. Monitor for patterns over time.";
159
+ }
160
+ } else {
161
+ suggestion = "No significant memory leaks detected.";
162
+ }
163
+ return {
164
+ hasLeak,
165
+ severity,
166
+ growthRate,
167
+ suggestion
168
+ };
169
+ };
@@ -0,0 +1,22 @@
1
+ import type { BenchmarkResult } from "../types.js";
2
+ export interface BenchmarkRunnerOptions {
3
+ command: string;
4
+ runs: number;
5
+ warmup: number;
6
+ concurrency: number;
7
+ cwd?: string;
8
+ timeout?: number;
9
+ env?: Record<string, string>;
10
+ verbose?: boolean;
11
+ }
12
+ export declare class BenchmarkRunner {
13
+ private options;
14
+ constructor(options: BenchmarkRunnerOptions);
15
+ run(): Promise<BenchmarkResult>;
16
+ private runWarmup;
17
+ private runBenchmark;
18
+ private calculateStatistics;
19
+ private calculateMemoryStats;
20
+ }
21
+ export declare const runBenchmark: (options: BenchmarkRunnerOptions) => Promise<BenchmarkResult>;
22
+ export declare const createBenchmarkRunner: (options: BenchmarkRunnerOptions) => BenchmarkRunner;
@@ -0,0 +1,157 @@
1
+ import { logger } from "@reliverse/dler-logger";
2
+ import pMap from "@reliverse/dler-mapper";
3
+ import { formatProgress } from "../utils/formatter.js";
4
+ import {
5
+ calculateMemoryAverage,
6
+ calculateStatistics,
7
+ findPeakMemory
8
+ } from "../utils/stats.js";
9
+ import { executeCommandWithMemoryTracking } from "./command.js";
10
+ export class BenchmarkRunner {
11
+ options;
12
+ constructor(options) {
13
+ this.options = options;
14
+ }
15
+ async run() {
16
+ const { command, runs, warmup, concurrency, verbose } = this.options;
17
+ const startTime = Date.now();
18
+ if (verbose) {
19
+ logger.info(`\u{1F680} Starting benchmark for: ${command}`);
20
+ logger.info(
21
+ ` Runs: ${runs}, Warmup: ${warmup}, Concurrency: ${concurrency}`
22
+ );
23
+ }
24
+ if (warmup > 0) {
25
+ if (verbose) {
26
+ logger.info(`\u{1F525} Running ${warmup} warmup iterations...`);
27
+ }
28
+ await this.runWarmup();
29
+ }
30
+ if (verbose) {
31
+ logger.info(`\u{1F4CA} Running ${runs} benchmark iterations...`);
32
+ }
33
+ const measurements = await this.runBenchmark();
34
+ const statistics = this.calculateStatistics(measurements);
35
+ const memory = this.calculateMemoryStats(measurements);
36
+ const executionTime = Date.now() - startTime;
37
+ const failures = measurements.filter((m) => !m.success);
38
+ const success = failures.length === 0;
39
+ if (verbose && failures.length > 0) {
40
+ logger.warn(`\u26A0\uFE0F ${failures.length} out of ${runs} runs failed`);
41
+ }
42
+ return {
43
+ command,
44
+ runs,
45
+ warmup,
46
+ concurrency,
47
+ measurements,
48
+ statistics,
49
+ memory,
50
+ executionTime,
51
+ success,
52
+ error: failures.length > 0 ? `${failures.length} runs failed` : void 0
53
+ };
54
+ }
55
+ async runWarmup() {
56
+ const { command, warmup, cwd, timeout, env } = this.options;
57
+ for (let i = 0; i < warmup; i++) {
58
+ try {
59
+ await executeCommandWithMemoryTracking(command, {
60
+ cwd,
61
+ timeout,
62
+ env
63
+ });
64
+ } catch {
65
+ }
66
+ }
67
+ }
68
+ async runBenchmark() {
69
+ const { command, runs, concurrency, cwd, timeout, env, verbose } = this.options;
70
+ const runIndices = Array.from({ length: runs }, (_, i) => i);
71
+ const measurements = await pMap(
72
+ runIndices,
73
+ async (runIndex) => {
74
+ if (verbose) {
75
+ logger.info(formatProgress(runIndex + 1, runs));
76
+ }
77
+ const measurement = await executeCommandWithMemoryTracking(command, {
78
+ cwd,
79
+ timeout,
80
+ env
81
+ });
82
+ measurement.run = runIndex + 1;
83
+ return measurement;
84
+ },
85
+ {
86
+ concurrency,
87
+ stopOnError: false
88
+ }
89
+ );
90
+ return measurements;
91
+ }
92
+ calculateStatistics(measurements) {
93
+ const durations = measurements.filter((m) => m.success).map((m) => m.duration);
94
+ if (durations.length === 0) {
95
+ return calculateStatistics([]);
96
+ }
97
+ return calculateStatistics(durations);
98
+ }
99
+ calculateMemoryStats(measurements) {
100
+ const successfulMeasurements = measurements.filter((m) => m.success);
101
+ if (successfulMeasurements.length === 0) {
102
+ return {
103
+ peak: {
104
+ rss: 0,
105
+ heapTotal: 0,
106
+ heapUsed: 0,
107
+ external: 0,
108
+ arrayBuffers: 0
109
+ },
110
+ average: {
111
+ rss: 0,
112
+ heapTotal: 0,
113
+ heapUsed: 0,
114
+ external: 0,
115
+ arrayBuffers: 0
116
+ },
117
+ growth: 0
118
+ };
119
+ }
120
+ const rssValues = successfulMeasurements.map((m) => m.memory.rss);
121
+ const heapTotalValues = successfulMeasurements.map(
122
+ (m) => m.memory.heapTotal
123
+ );
124
+ const heapUsedValues = successfulMeasurements.map((m) => m.memory.heapUsed);
125
+ const externalValues = successfulMeasurements.map((m) => m.memory.external);
126
+ const arrayBuffersValues = successfulMeasurements.map(
127
+ (m) => m.memory.arrayBuffers
128
+ );
129
+ const peak = {
130
+ rss: findPeakMemory(rssValues),
131
+ heapTotal: findPeakMemory(heapTotalValues),
132
+ heapUsed: findPeakMemory(heapUsedValues),
133
+ external: findPeakMemory(externalValues),
134
+ arrayBuffers: findPeakMemory(arrayBuffersValues)
135
+ };
136
+ const average = {
137
+ rss: calculateMemoryAverage(rssValues),
138
+ heapTotal: calculateMemoryAverage(heapTotalValues),
139
+ heapUsed: calculateMemoryAverage(heapUsedValues),
140
+ external: calculateMemoryAverage(externalValues),
141
+ arrayBuffers: calculateMemoryAverage(arrayBuffersValues)
142
+ };
143
+ const growth = rssValues.length > 1 ? rssValues[rssValues.length - 1] - rssValues[0] : 0;
144
+ return {
145
+ peak,
146
+ average,
147
+ growth
148
+ };
149
+ }
150
+ }
151
+ export const runBenchmark = async (options) => {
152
+ const runner = new BenchmarkRunner(options);
153
+ return runner.run();
154
+ };
155
+ export const createBenchmarkRunner = (options) => {
156
+ return new BenchmarkRunner(options);
157
+ };
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;