modestbench 0.9.0 → 0.9.2

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 (224) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cli/builder.cjs +259 -0
  3. package/dist/cli/builder.cjs.map +1 -0
  4. package/dist/cli/builder.d.cts +37 -0
  5. package/dist/cli/builder.d.cts.map +1 -0
  6. package/dist/cli/builder.d.ts +37 -0
  7. package/dist/cli/builder.d.ts.map +1 -0
  8. package/dist/cli/builder.js +255 -0
  9. package/dist/cli/builder.js.map +1 -0
  10. package/dist/cli/commands/baseline.cjs +4 -33
  11. package/dist/cli/commands/baseline.cjs.map +1 -1
  12. package/dist/cli/commands/baseline.d.cts.map +1 -1
  13. package/dist/cli/commands/baseline.d.ts.map +1 -1
  14. package/dist/cli/commands/baseline.js +2 -31
  15. package/dist/cli/commands/baseline.js.map +1 -1
  16. package/dist/cli/commands/history.cjs +2 -14
  17. package/dist/cli/commands/history.cjs.map +1 -1
  18. package/dist/cli/commands/history.d.cts.map +1 -1
  19. package/dist/cli/commands/history.d.ts.map +1 -1
  20. package/dist/cli/commands/history.js +1 -13
  21. package/dist/cli/commands/history.js.map +1 -1
  22. package/dist/cli/commands/init.cjs +2 -2
  23. package/dist/cli/commands/init.cjs.map +1 -1
  24. package/dist/cli/commands/init.js +2 -2
  25. package/dist/cli/commands/init.js.map +1 -1
  26. package/dist/cli/commands/run.cjs +3 -3
  27. package/dist/cli/commands/run.cjs.map +1 -1
  28. package/dist/cli/commands/run.d.cts +0 -13
  29. package/dist/cli/commands/run.d.cts.map +1 -1
  30. package/dist/cli/commands/run.d.ts +0 -13
  31. package/dist/cli/commands/run.d.ts.map +1 -1
  32. package/dist/cli/commands/run.js +1 -1
  33. package/dist/cli/commands/run.js.map +1 -1
  34. package/dist/cli/commands/test.cjs +1 -1
  35. package/dist/cli/commands/test.cjs.map +1 -1
  36. package/dist/cli/commands/test.js +1 -1
  37. package/dist/cli/commands/test.js.map +1 -1
  38. package/dist/cli/context.cjs +60 -0
  39. package/dist/cli/context.cjs.map +1 -0
  40. package/dist/cli/context.d.cts +28 -0
  41. package/dist/cli/context.d.cts.map +1 -0
  42. package/dist/cli/context.d.ts +28 -0
  43. package/dist/cli/context.d.ts.map +1 -0
  44. package/dist/cli/context.js +56 -0
  45. package/dist/cli/context.js.map +1 -0
  46. package/dist/cli/handlers.cjs +74 -0
  47. package/dist/cli/handlers.cjs.map +1 -0
  48. package/dist/cli/handlers.d.cts +13 -0
  49. package/dist/cli/handlers.d.cts.map +1 -0
  50. package/dist/cli/handlers.d.ts +13 -0
  51. package/dist/cli/handlers.d.ts.map +1 -0
  52. package/dist/cli/handlers.js +70 -0
  53. package/dist/cli/handlers.js.map +1 -0
  54. package/dist/cli/index.cjs +45 -978
  55. package/dist/cli/index.cjs.map +1 -1
  56. package/dist/cli/index.d.cts +6 -31
  57. package/dist/cli/index.d.cts.map +1 -1
  58. package/dist/cli/index.d.ts +6 -31
  59. package/dist/cli/index.d.ts.map +1 -1
  60. package/dist/cli/index.js +43 -974
  61. package/dist/cli/index.js.map +1 -1
  62. package/dist/cli/parsers/analyze.cjs +54 -0
  63. package/dist/cli/parsers/analyze.cjs.map +1 -0
  64. package/dist/cli/parsers/analyze.d.cts +37 -0
  65. package/dist/cli/parsers/analyze.d.cts.map +1 -0
  66. package/dist/cli/parsers/analyze.d.ts +37 -0
  67. package/dist/cli/parsers/analyze.d.ts.map +1 -0
  68. package/dist/cli/parsers/analyze.js +51 -0
  69. package/dist/cli/parsers/analyze.js.map +1 -0
  70. package/dist/cli/parsers/baseline.cjs +75 -0
  71. package/dist/cli/parsers/baseline.cjs.map +1 -0
  72. package/dist/cli/parsers/baseline.d.cts +59 -0
  73. package/dist/cli/parsers/baseline.d.cts.map +1 -0
  74. package/dist/cli/parsers/baseline.d.ts +59 -0
  75. package/dist/cli/parsers/baseline.d.ts.map +1 -0
  76. package/dist/cli/parsers/baseline.js +72 -0
  77. package/dist/cli/parsers/baseline.js.map +1 -0
  78. package/dist/cli/parsers/global.cjs +49 -0
  79. package/dist/cli/parsers/global.cjs.map +1 -0
  80. package/dist/cli/parsers/global.d.cts +45 -0
  81. package/dist/cli/parsers/global.d.cts.map +1 -0
  82. package/dist/cli/parsers/global.d.ts +45 -0
  83. package/dist/cli/parsers/global.d.ts.map +1 -0
  84. package/dist/cli/parsers/global.js +46 -0
  85. package/dist/cli/parsers/global.js.map +1 -0
  86. package/dist/cli/parsers/history.cjs +138 -0
  87. package/dist/cli/parsers/history.cjs.map +1 -0
  88. package/dist/cli/parsers/history.d.cts +108 -0
  89. package/dist/cli/parsers/history.d.cts.map +1 -0
  90. package/dist/cli/parsers/history.d.ts +108 -0
  91. package/dist/cli/parsers/history.d.ts.map +1 -0
  92. package/dist/cli/parsers/history.js +135 -0
  93. package/dist/cli/parsers/history.js.map +1 -0
  94. package/dist/cli/parsers/index.cjs +35 -0
  95. package/dist/cli/parsers/index.cjs.map +1 -0
  96. package/dist/cli/parsers/index.d.cts +15 -0
  97. package/dist/cli/parsers/index.d.cts.map +1 -0
  98. package/dist/cli/parsers/index.d.ts +15 -0
  99. package/dist/cli/parsers/index.d.ts.map +1 -0
  100. package/dist/cli/parsers/index.js +15 -0
  101. package/dist/cli/parsers/index.js.map +1 -0
  102. package/dist/cli/parsers/init.cjs +39 -0
  103. package/dist/cli/parsers/init.cjs.map +1 -0
  104. package/dist/cli/parsers/init.d.cts +32 -0
  105. package/dist/cli/parsers/init.d.cts.map +1 -0
  106. package/dist/cli/parsers/init.d.ts +32 -0
  107. package/dist/cli/parsers/init.d.ts.map +1 -0
  108. package/dist/cli/parsers/init.js +36 -0
  109. package/dist/cli/parsers/init.js.map +1 -0
  110. package/dist/cli/parsers/run.cjs +99 -0
  111. package/dist/cli/parsers/run.cjs.map +1 -0
  112. package/dist/cli/parsers/run.d.cts +62 -0
  113. package/dist/cli/parsers/run.d.cts.map +1 -0
  114. package/dist/cli/parsers/run.d.ts +62 -0
  115. package/dist/cli/parsers/run.d.ts.map +1 -0
  116. package/dist/cli/parsers/run.js +96 -0
  117. package/dist/cli/parsers/run.js.map +1 -0
  118. package/dist/cli/parsers/test.cjs +42 -0
  119. package/dist/cli/parsers/test.cjs.map +1 -0
  120. package/dist/cli/parsers/test.d.cts +31 -0
  121. package/dist/cli/parsers/test.d.cts.map +1 -0
  122. package/dist/cli/parsers/test.d.ts +31 -0
  123. package/dist/cli/parsers/test.d.ts.map +1 -0
  124. package/dist/cli/parsers/test.js +39 -0
  125. package/dist/cli/parsers/test.js.map +1 -0
  126. package/dist/cli/theme.cjs +35 -0
  127. package/dist/cli/theme.cjs.map +1 -0
  128. package/dist/cli/theme.d.cts +31 -0
  129. package/dist/cli/theme.d.cts.map +1 -0
  130. package/dist/cli/theme.d.ts +31 -0
  131. package/dist/cli/theme.d.ts.map +1 -0
  132. package/dist/cli/theme.js +32 -0
  133. package/dist/cli/theme.js.map +1 -0
  134. package/dist/config/budget-schema.cjs +1 -1
  135. package/dist/config/budget-schema.cjs.map +1 -1
  136. package/dist/config/budget-schema.js +1 -1
  137. package/dist/config/budget-schema.js.map +1 -1
  138. package/dist/core/engines/accurate-engine.cjs +1 -1
  139. package/dist/core/engines/accurate-engine.cjs.map +1 -1
  140. package/dist/core/engines/accurate-engine.d.cts.map +1 -1
  141. package/dist/core/engines/accurate-engine.d.ts.map +1 -1
  142. package/dist/core/engines/accurate-engine.js +1 -1
  143. package/dist/core/engines/accurate-engine.js.map +1 -1
  144. package/dist/errors/base.cjs +3 -12
  145. package/dist/errors/base.cjs.map +1 -1
  146. package/dist/errors/base.d.cts +0 -7
  147. package/dist/errors/base.d.cts.map +1 -1
  148. package/dist/errors/base.d.ts +0 -7
  149. package/dist/errors/base.d.ts.map +1 -1
  150. package/dist/errors/base.js +1 -9
  151. package/dist/errors/base.js.map +1 -1
  152. package/dist/formatters/history/compare.cjs +6 -6
  153. package/dist/formatters/history/compare.cjs.map +1 -1
  154. package/dist/formatters/history/compare.js +6 -6
  155. package/dist/formatters/history/compare.js.map +1 -1
  156. package/dist/formatters/history/show.cjs +2 -2
  157. package/dist/formatters/history/show.cjs.map +1 -1
  158. package/dist/formatters/history/show.js +2 -2
  159. package/dist/formatters/history/show.js.map +1 -1
  160. package/dist/formatters/history/trends.cjs +1 -1
  161. package/dist/formatters/history/trends.cjs.map +1 -1
  162. package/dist/formatters/history/trends.js +1 -1
  163. package/dist/formatters/history/trends.js.map +1 -1
  164. package/dist/reporters/human.cjs +3 -3
  165. package/dist/reporters/human.cjs.map +1 -1
  166. package/dist/reporters/human.d.cts.map +1 -1
  167. package/dist/reporters/human.d.ts.map +1 -1
  168. package/dist/reporters/human.js +3 -3
  169. package/dist/reporters/human.js.map +1 -1
  170. package/dist/reporters/nyan.cjs +1 -1
  171. package/dist/reporters/nyan.cjs.map +1 -1
  172. package/dist/reporters/nyan.js +1 -1
  173. package/dist/reporters/nyan.js.map +1 -1
  174. package/dist/services/budget-evaluator.cjs +2 -2
  175. package/dist/services/budget-evaluator.cjs.map +1 -1
  176. package/dist/services/budget-evaluator.js +2 -2
  177. package/dist/services/budget-evaluator.js.map +1 -1
  178. package/dist/services/config-manager.cjs +2 -2
  179. package/dist/services/config-manager.cjs.map +1 -1
  180. package/dist/services/config-manager.js +2 -2
  181. package/dist/services/config-manager.js.map +1 -1
  182. package/dist/services/profiler/profile-runner.cjs +11 -0
  183. package/dist/services/profiler/profile-runner.cjs.map +1 -1
  184. package/dist/services/profiler/profile-runner.d.cts +2 -0
  185. package/dist/services/profiler/profile-runner.d.cts.map +1 -1
  186. package/dist/services/profiler/profile-runner.d.ts +2 -0
  187. package/dist/services/profiler/profile-runner.d.ts.map +1 -1
  188. package/dist/services/profiler/profile-runner.js +11 -0
  189. package/dist/services/profiler/profile-runner.js.map +1 -1
  190. package/dist/services/reporter-registry.cjs +8 -8
  191. package/dist/services/reporter-registry.cjs.map +1 -1
  192. package/dist/services/reporter-registry.js +8 -8
  193. package/dist/services/reporter-registry.js.map +1 -1
  194. package/package.json +7 -9
  195. package/src/cli/builder.ts +387 -0
  196. package/src/cli/commands/baseline.ts +7 -33
  197. package/src/cli/commands/history.ts +1 -16
  198. package/src/cli/commands/init.ts +2 -2
  199. package/src/cli/commands/run.ts +1 -1
  200. package/src/cli/commands/test.ts +1 -1
  201. package/src/cli/context.ts +117 -0
  202. package/src/cli/handlers.ts +76 -0
  203. package/src/cli/index.ts +49 -1194
  204. package/src/cli/parsers/analyze.ts +61 -0
  205. package/src/cli/parsers/baseline.ts +92 -0
  206. package/src/cli/parsers/global.ts +51 -0
  207. package/src/cli/parsers/history.ts +168 -0
  208. package/src/cli/parsers/index.ts +28 -0
  209. package/src/cli/parsers/init.ts +45 -0
  210. package/src/cli/parsers/run.ts +118 -0
  211. package/src/cli/parsers/test.ts +46 -0
  212. package/src/cli/theme.ts +33 -0
  213. package/src/config/budget-schema.ts +1 -1
  214. package/src/core/engines/accurate-engine.ts +1 -1
  215. package/src/errors/base.ts +1 -10
  216. package/src/formatters/history/compare.ts +6 -6
  217. package/src/formatters/history/show.ts +2 -2
  218. package/src/formatters/history/trends.ts +1 -1
  219. package/src/reporters/human.ts +5 -3
  220. package/src/reporters/nyan.ts +1 -1
  221. package/src/services/budget-evaluator.ts +2 -2
  222. package/src/services/config-manager.ts +2 -2
  223. package/src/services/profiler/profile-runner.ts +15 -0
  224. package/src/services/reporter-registry.ts +8 -8
@@ -51,8 +51,8 @@ export class HistoryCompareFormatter implements HistoryFormatter<CompareResult>
51
51
  lines.push('');
52
52
 
53
53
  for (const comparison of data.tasksInBoth) {
54
- const mean1 = comparison.run1!.mean / 1000000; // Convert to ms
55
- const mean2 = comparison.run2!.mean / 1000000;
54
+ const mean1 = comparison.run1!.mean / 1_000_000; // Convert to ms
55
+ const mean2 = comparison.run2!.mean / 1_000_000;
56
56
  const changeSign = comparison.percentChange >= 0 ? '+' : '';
57
57
  const changeStr = `${changeSign}${comparison.percentChange.toFixed(1)}%`;
58
58
 
@@ -73,8 +73,8 @@ export class HistoryCompareFormatter implements HistoryFormatter<CompareResult>
73
73
  );
74
74
 
75
75
  // Min - highlight higher number
76
- const min1 = comparison.run1!.min / 1000000;
77
- const min2 = comparison.run2!.min / 1000000;
76
+ const min1 = comparison.run1!.min / 1_000_000;
77
+ const min2 = comparison.run2!.min / 1_000_000;
78
78
  const minHigher = min2 > min1;
79
79
  const min1Str = minHigher
80
80
  ? colorize('magenta', `${min1.toFixed(3)}ms`)
@@ -87,8 +87,8 @@ export class HistoryCompareFormatter implements HistoryFormatter<CompareResult>
87
87
  );
88
88
 
89
89
  // Max - highlight higher number
90
- const max1 = comparison.run1!.max / 1000000;
91
- const max2 = comparison.run2!.max / 1000000;
90
+ const max1 = comparison.run1!.max / 1_000_000;
91
+ const max2 = comparison.run2!.max / 1_000_000;
92
92
  const maxHigher = max2 > max1;
93
93
  const max1Str = maxHigher
94
94
  ? colorize('magenta', `${max1.toFixed(3)}ms`)
@@ -148,8 +148,8 @@ const formatTime = (ns: number): string => {
148
148
  if (ns < 1000) {
149
149
  return `${ns.toFixed(2)}ns`;
150
150
  }
151
- if (ns < 1000000) {
151
+ if (ns < 1_000_000) {
152
152
  return `${(ns / 1000).toFixed(3)}µs`;
153
153
  }
154
- return `${(ns / 1000000).toFixed(3)}ms`;
154
+ return `${(ns / 1_000_000).toFixed(3)}ms`;
155
155
  };
@@ -24,7 +24,7 @@ const NS_PER_MS = 1_000_000;
24
24
  /**
25
25
  * Nanoseconds per microsecond conversion constant
26
26
  */
27
- const NS_PER_US = 1_000;
27
+ const NS_PER_US = 1000;
28
28
 
29
29
  /**
30
30
  * Intelligently format a time range with appropriate precision Displays
@@ -234,7 +234,7 @@ export class HumanReporter extends BaseReporter {
234
234
  );
235
235
  }
236
236
  this.printLine(
237
- `${this.colorize('cyan', ansiChars.approx + ' Duration:')} ${this.colorize('brightWhite', BaseReporter.formatDuration(duration * 1000000))}`,
237
+ `${this.colorize('cyan', ansiChars.approx + ' Duration:')} ${this.colorize('brightWhite', BaseReporter.formatDuration(duration * 1_000_000))}`,
238
238
  );
239
239
  this.printLine();
240
240
 
@@ -463,7 +463,7 @@ export class HumanReporter extends BaseReporter {
463
463
  });
464
464
 
465
465
  const durationStr = BaseReporter.formatDuration(
466
- result.duration * 1000000,
466
+ result.duration * 1_000_000,
467
467
  );
468
468
 
469
469
  // Display suite setup failure
@@ -487,7 +487,9 @@ export class HumanReporter extends BaseReporter {
487
487
  const passed = result.tasks.filter((t) => !t.error && !t.aborted).length;
488
488
  const failed = result.tasks.filter((t) => t.error).length;
489
489
  const aborted = result.tasks.filter((t) => t.aborted).length;
490
- const durationStr = BaseReporter.formatDuration(result.duration * 1000000); // ms to ns
490
+ const durationStr = BaseReporter.formatDuration(
491
+ result.duration * 1_000_000,
492
+ ); // ms to ns
491
493
 
492
494
  // Build summary parts
493
495
  const parts: string[] = [];
@@ -345,7 +345,7 @@ export class NyanReporter extends BaseReporter {
345
345
  */
346
346
  private printEpilogue(run: BenchmarkRun): void {
347
347
  const duration = Date.now() - this.startTime;
348
- const durationStr = BaseReporter.formatDuration(duration * 1000000);
348
+ const durationStr = BaseReporter.formatDuration(duration * 1_000_000);
349
349
 
350
350
  console.log();
351
351
  console.log(
@@ -37,10 +37,10 @@ export class BudgetEvaluator {
37
37
  * Format time in nanoseconds to human-readable string
38
38
  */
39
39
  private static formatTime(this: void, nanoseconds: number): string {
40
- if (nanoseconds < 1_000) {
40
+ if (nanoseconds < 1000) {
41
41
  return `${nanoseconds.toFixed(0)}ns`;
42
42
  } else if (nanoseconds < 1_000_000) {
43
- return `${(nanoseconds / 1_000).toFixed(2)}μs`;
43
+ return `${(nanoseconds / 1000).toFixed(2)}μs`;
44
44
  } else if (nanoseconds < 1_000_000_000) {
45
45
  return `${(nanoseconds / 1_000_000).toFixed(2)}ms`;
46
46
  } else {
@@ -63,7 +63,7 @@ const DEFAULT_CONFIG: ModestBenchConfig = {
63
63
  tags: [],
64
64
  thresholds: {},
65
65
  time: 1000, // 1 second minimum for tinybench to gather samples
66
- timeout: 30000, // 30 seconds
66
+ timeout: 30_000, // 30 seconds
67
67
  verbose: false, // No verbose output by default
68
68
  warmup: 30, // Light warmup by default - enough for basic JIT optimization
69
69
  };
@@ -291,7 +291,7 @@ export class ModestBenchConfigurationManager implements ConfigurationManager {
291
291
  }
292
292
 
293
293
  // Warn about potentially long runtime
294
- if (validConfig.iterations > 1000 && validConfig.time > 60000) {
294
+ if (validConfig.iterations > 1000 && validConfig.time > 60_000) {
295
295
  warnings.push({
296
296
  code: 'LONG_RUNTIME_WARNING',
297
297
  file: 'configuration',
@@ -26,17 +26,32 @@ interface RunOptions {
26
26
  timeout?: number;
27
27
  }
28
28
 
29
+ /**
30
+ * Node.js major version number
31
+ */
32
+ const nodeMajorVersion = Number(process.versions.node.split('.')[0]);
33
+
29
34
  /**
30
35
  * Run a command with Node.js profiling enabled
31
36
  *
32
37
  * @param command - Command to run (e.g., "npm test")
33
38
  * @param options - Execution options
34
39
  * @returns Path to generated *.cpuprofile file
40
+ * @throws Error if running on Node.js 20 (--cpu-prof not allowed in
41
+ * NODE_OPTIONS)
35
42
  */
36
43
  export const runWithProfiling = async (
37
44
  command: string,
38
45
  options: RunOptions = {},
39
46
  ): Promise<string> => {
47
+ // Node.js 20 blocks --cpu-prof in NODE_OPTIONS for security reasons
48
+ if (nodeMajorVersion === 20) {
49
+ throw new Error(
50
+ 'CPU profiling requires Node.js 22 or later. ' +
51
+ 'Node.js 20 blocks --cpu-prof in NODE_OPTIONS for security reasons.',
52
+ );
53
+ }
54
+
40
55
  const cwd = options.cwd || process.cwd();
41
56
 
42
57
  // Create profiles directory
@@ -39,12 +39,12 @@ export abstract class BaseReporter implements Reporter {
39
39
  protected static formatDuration(this: void, nanoseconds: number): string {
40
40
  if (nanoseconds < 1000) {
41
41
  return `${nanoseconds.toFixed(2)}ns`;
42
- } else if (nanoseconds < 1000000) {
42
+ } else if (nanoseconds < 1_000_000) {
43
43
  return `${(nanoseconds / 1000).toFixed(2)}μs`;
44
- } else if (nanoseconds < 1000000000) {
45
- return `${(nanoseconds / 1000000).toFixed(2)}ms`;
44
+ } else if (nanoseconds < 1_000_000_000) {
45
+ return `${(nanoseconds / 1_000_000).toFixed(2)}ms`;
46
46
  } else {
47
- return `${(nanoseconds / 1000000000).toFixed(2)}s`;
47
+ return `${(nanoseconds / 1_000_000_000).toFixed(2)}s`;
48
48
  }
49
49
  }
50
50
 
@@ -57,12 +57,12 @@ export abstract class BaseReporter implements Reporter {
57
57
  ): string {
58
58
  if (opsPerSecond < 1000) {
59
59
  return `${opsPerSecond.toFixed(2)} ops/sec`;
60
- } else if (opsPerSecond < 1000000) {
60
+ } else if (opsPerSecond < 1_000_000) {
61
61
  return `${(opsPerSecond / 1000).toFixed(2)}K ops/sec`;
62
- } else if (opsPerSecond < 1000000000) {
63
- return `${(opsPerSecond / 1000000).toFixed(2)}M ops/sec`;
62
+ } else if (opsPerSecond < 1_000_000_000) {
63
+ return `${(opsPerSecond / 1_000_000).toFixed(2)}M ops/sec`;
64
64
  } else {
65
- return `${(opsPerSecond / 1000000000).toFixed(2)}B ops/sec`;
65
+ return `${(opsPerSecond / 1_000_000_000).toFixed(2)}B ops/sec`;
66
66
  }
67
67
  }
68
68