@10up/block-renderer-benchmark 0.1.4

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 (77) hide show
  1. package/dist/analysis/comparison.d.ts +29 -0
  2. package/dist/analysis/comparison.d.ts.map +1 -0
  3. package/dist/analysis/comparison.js +94 -0
  4. package/dist/analysis/comparison.js.map +1 -0
  5. package/dist/analysis/index.d.ts +6 -0
  6. package/dist/analysis/index.d.ts.map +1 -0
  7. package/dist/analysis/index.js +6 -0
  8. package/dist/analysis/index.js.map +1 -0
  9. package/dist/analysis/regression.d.ts +34 -0
  10. package/dist/analysis/regression.d.ts.map +1 -0
  11. package/dist/analysis/regression.js +63 -0
  12. package/dist/analysis/regression.js.map +1 -0
  13. package/dist/cli/commands/compare.d.ts +9 -0
  14. package/dist/cli/commands/compare.d.ts.map +1 -0
  15. package/dist/cli/commands/compare.js +142 -0
  16. package/dist/cli/commands/compare.js.map +1 -0
  17. package/dist/cli/commands/report.d.ts +9 -0
  18. package/dist/cli/commands/report.d.ts.map +1 -0
  19. package/dist/cli/commands/report.js +158 -0
  20. package/dist/cli/commands/report.js.map +1 -0
  21. package/dist/cli/commands/run.d.ts +9 -0
  22. package/dist/cli/commands/run.d.ts.map +1 -0
  23. package/dist/cli/commands/run.js +107 -0
  24. package/dist/cli/commands/run.js.map +1 -0
  25. package/dist/cli/index.d.ts +8 -0
  26. package/dist/cli/index.d.ts.map +1 -0
  27. package/dist/cli/index.js +165 -0
  28. package/dist/cli/index.js.map +1 -0
  29. package/dist/index.d.ts +16 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +19 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/reporters/console-reporter.d.ts +47 -0
  34. package/dist/reporters/console-reporter.d.ts.map +1 -0
  35. package/dist/reporters/console-reporter.js +191 -0
  36. package/dist/reporters/console-reporter.js.map +1 -0
  37. package/dist/reporters/index.d.ts +6 -0
  38. package/dist/reporters/index.d.ts.map +1 -0
  39. package/dist/reporters/index.js +6 -0
  40. package/dist/reporters/index.js.map +1 -0
  41. package/dist/reporters/markdown-reporter.d.ts +32 -0
  42. package/dist/reporters/markdown-reporter.d.ts.map +1 -0
  43. package/dist/reporters/markdown-reporter.js +133 -0
  44. package/dist/reporters/markdown-reporter.js.map +1 -0
  45. package/dist/runner/benchmark-runner.d.ts +37 -0
  46. package/dist/runner/benchmark-runner.d.ts.map +1 -0
  47. package/dist/runner/benchmark-runner.js +133 -0
  48. package/dist/runner/benchmark-runner.js.map +1 -0
  49. package/dist/runner/index.d.ts +6 -0
  50. package/dist/runner/index.d.ts.map +1 -0
  51. package/dist/runner/index.js +6 -0
  52. package/dist/runner/index.js.map +1 -0
  53. package/dist/runner/timing.d.ts +43 -0
  54. package/dist/runner/timing.d.ts.map +1 -0
  55. package/dist/runner/timing.js +115 -0
  56. package/dist/runner/timing.js.map +1 -0
  57. package/dist/runner/vitest-reporter.d.ts +38 -0
  58. package/dist/runner/vitest-reporter.d.ts.map +1 -0
  59. package/dist/runner/vitest-reporter.js +134 -0
  60. package/dist/runner/vitest-reporter.js.map +1 -0
  61. package/dist/storage/index.d.ts +6 -0
  62. package/dist/storage/index.d.ts.map +1 -0
  63. package/dist/storage/index.js +6 -0
  64. package/dist/storage/index.js.map +1 -0
  65. package/dist/storage/json-storage.d.ts +59 -0
  66. package/dist/storage/json-storage.d.ts.map +1 -0
  67. package/dist/storage/json-storage.js +142 -0
  68. package/dist/storage/json-storage.js.map +1 -0
  69. package/dist/storage/sqlite-storage.d.ts +72 -0
  70. package/dist/storage/sqlite-storage.d.ts.map +1 -0
  71. package/dist/storage/sqlite-storage.js +305 -0
  72. package/dist/storage/sqlite-storage.js.map +1 -0
  73. package/dist/types.d.ts +253 -0
  74. package/dist/types.d.ts.map +1 -0
  75. package/dist/types.js +21 -0
  76. package/dist/types.js.map +1 -0
  77. package/package.json +79 -0
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Comparison utilities for benchmark results
3
+ */
4
+ import type { BaselineEntry, BenchmarkMeasurement, ComparisonResult, ComparisonSummary, RegressionThresholds } from '../types.js';
5
+ /**
6
+ * Compare a measurement against a baseline entry
7
+ */
8
+ export declare function compareMeasurements(baseline: BaselineEntry, current: BaselineEntry, name: string, thresholds?: RegressionThresholds): ComparisonResult;
9
+ /**
10
+ * Compare two sets of baselines
11
+ */
12
+ export declare function compareBaselines(baseline: Record<string, BaselineEntry>, current: Record<string, BaselineEntry>, thresholds?: RegressionThresholds): ComparisonResult[];
13
+ /**
14
+ * Compare benchmark measurements to baselines
15
+ */
16
+ export declare function compareMeasurementsToBaselines(baselines: Record<string, BaselineEntry>, measurements: BenchmarkMeasurement[], thresholds?: RegressionThresholds): ComparisonResult[];
17
+ /**
18
+ * Create a summary from comparison results
19
+ */
20
+ export declare function summarizeComparison(results: ComparisonResult[]): ComparisonSummary;
21
+ /**
22
+ * Sort comparison results by severity (regressions first, by magnitude)
23
+ */
24
+ export declare function sortByRegression(results: ComparisonResult[]): ComparisonResult[];
25
+ /**
26
+ * Filter results to only include significant changes
27
+ */
28
+ export declare function filterSignificant(results: ComparisonResult[], thresholds?: RegressionThresholds): ComparisonResult[];
29
+ //# sourceMappingURL=comparison.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparison.d.ts","sourceRoot":"","sources":["../../src/analysis/comparison.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,aAAa,CAAC;AASrB;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,oBAAoD,GAC/D,gBAAgB,CAiBlB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,EACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,EACtC,UAAU,GAAE,oBAAoD,GAC/D,gBAAgB,EAAE,CAWpB;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,EACxC,YAAY,EAAE,oBAAoB,EAAE,EACpC,UAAU,GAAE,oBAAoD,GAC/D,gBAAgB,EAAE,CAiBpB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,iBAAiB,CAalF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAShF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,gBAAgB,EAAE,EAC3B,UAAU,GAAE,oBAAoD,GAC/D,gBAAgB,EAAE,CAKpB"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Comparison utilities for benchmark results
3
+ */
4
+ import { DEFAULT_REGRESSION_THRESHOLDS } from '../types.js';
5
+ import { percentageChange, detectRegression, detectImprovement, getComparisonStatus, } from './regression.js';
6
+ /**
7
+ * Compare a measurement against a baseline entry
8
+ */
9
+ export function compareMeasurements(baseline, current, name, thresholds = DEFAULT_REGRESSION_THRESHOLDS) {
10
+ const meanChange = percentageChange(baseline.mean, current.mean);
11
+ const p95Change = percentageChange(baseline.p95, current.p95);
12
+ const isRegression = detectRegression(baseline, current, thresholds);
13
+ const isImprovement = detectImprovement(baseline, current, thresholds);
14
+ const status = getComparisonStatus(baseline, current, thresholds);
15
+ return {
16
+ name,
17
+ baseline,
18
+ current,
19
+ meanChange,
20
+ p95Change,
21
+ isRegression,
22
+ isImprovement,
23
+ status,
24
+ };
25
+ }
26
+ /**
27
+ * Compare two sets of baselines
28
+ */
29
+ export function compareBaselines(baseline, current, thresholds = DEFAULT_REGRESSION_THRESHOLDS) {
30
+ const results = [];
31
+ // Compare all benchmarks that exist in both sets
32
+ for (const name of Object.keys(current)) {
33
+ if (baseline[name]) {
34
+ results.push(compareMeasurements(baseline[name], current[name], name, thresholds));
35
+ }
36
+ }
37
+ return results;
38
+ }
39
+ /**
40
+ * Compare benchmark measurements to baselines
41
+ */
42
+ export function compareMeasurementsToBaselines(baselines, measurements, thresholds = DEFAULT_REGRESSION_THRESHOLDS) {
43
+ const results = [];
44
+ for (const measurement of measurements) {
45
+ const baseline = baselines[measurement.name];
46
+ if (baseline) {
47
+ const current = {
48
+ mean: measurement.timing.mean,
49
+ median: measurement.timing.median,
50
+ p95: measurement.timing.p95,
51
+ iterations: measurement.iterations,
52
+ };
53
+ results.push(compareMeasurements(baseline, current, measurement.name, thresholds));
54
+ }
55
+ }
56
+ return results;
57
+ }
58
+ /**
59
+ * Create a summary from comparison results
60
+ */
61
+ export function summarizeComparison(results) {
62
+ const regressions = results.filter((r) => r.isRegression).length;
63
+ const improvements = results.filter((r) => r.isImprovement).length;
64
+ const unchanged = results.length - regressions - improvements;
65
+ return {
66
+ total: results.length,
67
+ regressions,
68
+ improvements,
69
+ unchanged,
70
+ results,
71
+ hasRegressions: regressions > 0,
72
+ };
73
+ }
74
+ /**
75
+ * Sort comparison results by severity (regressions first, by magnitude)
76
+ */
77
+ export function sortByRegression(results) {
78
+ return [...results].sort((a, b) => {
79
+ // Regressions first
80
+ if (a.isRegression && !b.isRegression)
81
+ return -1;
82
+ if (!a.isRegression && b.isRegression)
83
+ return 1;
84
+ // Then by magnitude of change (descending)
85
+ return Math.abs(b.meanChange) - Math.abs(a.meanChange);
86
+ });
87
+ }
88
+ /**
89
+ * Filter results to only include significant changes
90
+ */
91
+ export function filterSignificant(results, thresholds = DEFAULT_REGRESSION_THRESHOLDS) {
92
+ return results.filter((r) => Math.abs(r.meanChange) > Math.min(thresholds.regressionThreshold, thresholds.improvementThreshold));
93
+ }
94
+ //# sourceMappingURL=comparison.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparison.js","sourceRoot":"","sources":["../../src/analysis/comparison.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Analysis module exports
3
+ */
4
+ export { percentageChange, detectRegression, detectImprovement, getComparisonStatus, calculateConfidence, } from './regression.js';
5
+ export { compareMeasurements, compareBaselines, compareMeasurementsToBaselines, summarizeComparison, sortByRegression, filterSignificant, } from './comparison.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analysis/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,8BAA8B,EAC9B,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Analysis module exports
3
+ */
4
+ export { percentageChange, detectRegression, detectImprovement, getComparisonStatus, calculateConfidence, } from './regression.js';
5
+ export { compareMeasurements, compareBaselines, compareMeasurementsToBaselines, summarizeComparison, sortByRegression, filterSignificant, } from './comparison.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analysis/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,8BAA8B,EAC9B,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Regression detection utilities
3
+ */
4
+ import type { BaselineEntry, RegressionThresholds } from '../types.js';
5
+ /**
6
+ * Calculate the percentage change between two values
7
+ */
8
+ export declare function percentageChange(baseline: number, current: number): number;
9
+ /**
10
+ * Detect if a measurement is a regression
11
+ *
12
+ * A regression is when the current measurement is significantly slower
13
+ * than the baseline (positive change exceeding threshold)
14
+ */
15
+ export declare function detectRegression(baseline: BaselineEntry, current: BaselineEntry, thresholds?: RegressionThresholds): boolean;
16
+ /**
17
+ * Detect if a measurement is an improvement
18
+ *
19
+ * An improvement is when the current measurement is significantly faster
20
+ * than the baseline (negative change exceeding threshold)
21
+ */
22
+ export declare function detectImprovement(baseline: BaselineEntry, current: BaselineEntry, thresholds?: RegressionThresholds): boolean;
23
+ /**
24
+ * Get the status of a comparison
25
+ */
26
+ export declare function getComparisonStatus(baseline: BaselineEntry, current: BaselineEntry, thresholds?: RegressionThresholds): 'regression' | 'improvement' | 'unchanged';
27
+ /**
28
+ * Calculate a confidence score for the comparison
29
+ *
30
+ * Higher score = more confident the change is real
31
+ * Based on the magnitude of change and consistency of measurements
32
+ */
33
+ export declare function calculateConfidence(meanChange: number, p95Change: number, threshold: number): number;
34
+ //# sourceMappingURL=regression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regression.d.ts","sourceRoot":"","sources":["../../src/analysis/regression.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACrB,MAAM,aAAa,CAAC;AAGrB;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,aAAa,EACtB,UAAU,GAAE,oBAAoD,GAC/D,OAAO,CAGT;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,aAAa,EACtB,UAAU,GAAE,oBAAoD,GAC/D,OAAO,CAGT;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,aAAa,EACtB,UAAU,GAAE,oBAAoD,GAC/D,YAAY,GAAG,aAAa,GAAG,WAAW,CAQ5C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAeR"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Regression detection utilities
3
+ */
4
+ import { DEFAULT_REGRESSION_THRESHOLDS } from '../types.js';
5
+ /**
6
+ * Calculate the percentage change between two values
7
+ */
8
+ export function percentageChange(baseline, current) {
9
+ if (baseline === 0)
10
+ return current > 0 ? 100 : 0;
11
+ return ((current - baseline) / baseline) * 100;
12
+ }
13
+ /**
14
+ * Detect if a measurement is a regression
15
+ *
16
+ * A regression is when the current measurement is significantly slower
17
+ * than the baseline (positive change exceeding threshold)
18
+ */
19
+ export function detectRegression(baseline, current, thresholds = DEFAULT_REGRESSION_THRESHOLDS) {
20
+ const meanChange = percentageChange(baseline.mean, current.mean);
21
+ return meanChange > thresholds.regressionThreshold;
22
+ }
23
+ /**
24
+ * Detect if a measurement is an improvement
25
+ *
26
+ * An improvement is when the current measurement is significantly faster
27
+ * than the baseline (negative change exceeding threshold)
28
+ */
29
+ export function detectImprovement(baseline, current, thresholds = DEFAULT_REGRESSION_THRESHOLDS) {
30
+ const meanChange = percentageChange(baseline.mean, current.mean);
31
+ return meanChange < -thresholds.improvementThreshold;
32
+ }
33
+ /**
34
+ * Get the status of a comparison
35
+ */
36
+ export function getComparisonStatus(baseline, current, thresholds = DEFAULT_REGRESSION_THRESHOLDS) {
37
+ if (detectRegression(baseline, current, thresholds)) {
38
+ return 'regression';
39
+ }
40
+ if (detectImprovement(baseline, current, thresholds)) {
41
+ return 'improvement';
42
+ }
43
+ return 'unchanged';
44
+ }
45
+ /**
46
+ * Calculate a confidence score for the comparison
47
+ *
48
+ * Higher score = more confident the change is real
49
+ * Based on the magnitude of change and consistency of measurements
50
+ */
51
+ export function calculateConfidence(meanChange, p95Change, threshold) {
52
+ // How much the change exceeds the threshold
53
+ const excessRatio = Math.abs(meanChange) / threshold;
54
+ // Are mean and p95 changes consistent in direction?
55
+ const sameDirection = (meanChange >= 0) === (p95Change >= 0);
56
+ let confidence = Math.min(excessRatio, 2) / 2; // 0-1 scale
57
+ // Boost confidence if changes are consistent
58
+ if (sameDirection) {
59
+ confidence *= 1.2;
60
+ }
61
+ return Math.min(confidence, 1);
62
+ }
63
+ //# sourceMappingURL=regression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regression.js","sourceRoot":"","sources":["../../src/analysis/regression.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAC;AAE5D;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,OAAe;IAChE,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC,GAAG,GAAG,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAuB,EACvB,OAAsB,EACtB,aAAmC,6BAA6B;IAEhE,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,OAAO,UAAU,GAAG,UAAU,CAAC,mBAAmB,CAAC;AACrD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAuB,EACvB,OAAsB,EACtB,aAAmC,6BAA6B;IAEhE,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,OAAO,UAAU,GAAG,CAAC,UAAU,CAAC,oBAAoB,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAuB,EACvB,OAAsB,EACtB,aAAmC,6BAA6B;IAEhE,IAAI,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC;QACpD,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IAAI,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC;QACrD,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,UAAkB,EAClB,SAAiB,EACjB,SAAiB;IAEjB,4CAA4C;IAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;IAErD,oDAAoD;IACpD,MAAM,aAAa,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;IAE7D,IAAI,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY;IAE3D,6CAA6C;IAC7C,IAAI,aAAa,EAAE,CAAC;QAClB,UAAU,IAAI,GAAG,CAAC;IACpB,CAAC;IAED,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Compare benchmarks command
3
+ */
4
+ import type { CompareOptions } from '../../types.js';
5
+ /**
6
+ * Run the compare command
7
+ */
8
+ export declare function compareCommand(options: CompareOptions): Promise<void>;
9
+ //# sourceMappingURL=compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/compare.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AA0BrD;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA4H3E"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Compare benchmarks command
3
+ */
4
+ import * as fs from 'fs';
5
+ import * as path from 'path';
6
+ import { JsonStorage } from '../../storage/json-storage.js';
7
+ import { SqliteStorage, DEFAULT_DB_PATH } from '../../storage/sqlite-storage.js';
8
+ import { compareBaselines, summarizeComparison } from '../../analysis/comparison.js';
9
+ import { ConsoleReporter } from '../../reporters/console-reporter.js';
10
+ import { MarkdownReporter } from '../../reporters/markdown-reporter.js';
11
+ import { DEFAULT_REGRESSION_THRESHOLDS } from '../../types.js';
12
+ /**
13
+ * Find the project root
14
+ */
15
+ function findProjectRoot() {
16
+ let dir = process.cwd();
17
+ while (dir !== path.dirname(dir)) {
18
+ const pkgPath = path.join(dir, 'package.json');
19
+ if (fs.existsSync(pkgPath)) {
20
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
21
+ if (pkg.workspaces || fs.existsSync(path.join(dir, 'pnpm-workspace.yaml'))) {
22
+ return dir;
23
+ }
24
+ }
25
+ dir = path.dirname(dir);
26
+ }
27
+ return process.cwd();
28
+ }
29
+ /**
30
+ * Run the compare command
31
+ */
32
+ export async function compareCommand(options) {
33
+ const projectRoot = findProjectRoot();
34
+ // Load baseline
35
+ const baselinePath = path.isAbsolute(options.baseline)
36
+ ? options.baseline
37
+ : path.join(projectRoot, options.baseline);
38
+ if (!fs.existsSync(baselinePath)) {
39
+ console.error(`Baseline file not found: ${baselinePath}`);
40
+ console.error('\nRun benchmarks with --update-baseline first to create a baseline.');
41
+ process.exit(1);
42
+ }
43
+ const jsonStorage = new JsonStorage(baselinePath);
44
+ const baselineData = jsonStorage.load();
45
+ if (!baselineData) {
46
+ console.error('Failed to load baseline file');
47
+ process.exit(1);
48
+ }
49
+ // Load current results
50
+ let currentBaselines;
51
+ if (options.current) {
52
+ // Load from specified file
53
+ const currentPath = path.isAbsolute(options.current)
54
+ ? options.current
55
+ : path.join(projectRoot, options.current);
56
+ if (!fs.existsSync(currentPath)) {
57
+ console.error(`Current results file not found: ${currentPath}`);
58
+ process.exit(1);
59
+ }
60
+ const currentStorage = new JsonStorage(currentPath);
61
+ const currentData = currentStorage.load();
62
+ if (!currentData) {
63
+ console.error('Failed to load current results file');
64
+ process.exit(1);
65
+ }
66
+ currentBaselines = currentData.baselines;
67
+ }
68
+ else {
69
+ // Try to load from SQLite database
70
+ const dbPath = path.join(projectRoot, DEFAULT_DB_PATH);
71
+ if (fs.existsSync(dbPath)) {
72
+ const sqliteStorage = new SqliteStorage(dbPath);
73
+ const latestRun = sqliteStorage.getLatestRun();
74
+ sqliteStorage.close();
75
+ if (latestRun) {
76
+ currentBaselines = {};
77
+ for (const m of latestRun.measurements) {
78
+ currentBaselines[m.name] = {
79
+ mean: m.timing.mean,
80
+ median: m.timing.median,
81
+ p95: m.timing.p95,
82
+ };
83
+ }
84
+ }
85
+ else {
86
+ console.error('No benchmark runs found in database');
87
+ console.error('Run benchmarks first or specify --current <path>');
88
+ process.exit(1);
89
+ }
90
+ }
91
+ else {
92
+ console.error('No database found and no --current specified');
93
+ console.error('Run benchmarks first or specify --current <path>');
94
+ process.exit(1);
95
+ }
96
+ }
97
+ // Compare
98
+ const thresholds = {
99
+ ...DEFAULT_REGRESSION_THRESHOLDS,
100
+ regressionThreshold: options.threshold ?? DEFAULT_REGRESSION_THRESHOLDS.regressionThreshold,
101
+ };
102
+ const results = compareBaselines(baselineData.baselines, currentBaselines, thresholds);
103
+ const summary = summarizeComparison(results);
104
+ // Output
105
+ const format = options.format || 'console';
106
+ let output;
107
+ if (format === 'console') {
108
+ const reporter = new ConsoleReporter();
109
+ reporter.reportComparison(summary);
110
+ output = ''; // Console reporter outputs directly
111
+ }
112
+ else if (format === 'markdown') {
113
+ const reporter = new MarkdownReporter();
114
+ output = reporter.reportComparison(summary);
115
+ console.log(output);
116
+ }
117
+ else if (format === 'json') {
118
+ output = JSON.stringify(summary, null, 2);
119
+ console.log(output);
120
+ }
121
+ else {
122
+ output = '';
123
+ }
124
+ // Write to file if specified
125
+ if (options.output && output) {
126
+ const outputPath = path.isAbsolute(options.output)
127
+ ? options.output
128
+ : path.join(projectRoot, options.output);
129
+ const outputDir = path.dirname(outputPath);
130
+ if (!fs.existsSync(outputDir)) {
131
+ fs.mkdirSync(outputDir, { recursive: true });
132
+ }
133
+ fs.writeFileSync(outputPath, output);
134
+ console.log(`\nOutput written to: ${outputPath}`);
135
+ }
136
+ // Exit with error if regressions detected and flag is set
137
+ if (options.failOnRegression && summary.hasRegressions) {
138
+ console.error(`\n${summary.regressions} regression(s) detected!`);
139
+ process.exit(1);
140
+ }
141
+ }
142
+ //# sourceMappingURL=compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../../../src/cli/commands/compare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Generate benchmark report command
3
+ */
4
+ import type { ReportOptions } from '../../types.js';
5
+ /**
6
+ * Run the report command
7
+ */
8
+ export declare function reportCommand(options: ReportOptions): Promise<void>;
9
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/report.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,gBAAgB,CAAC;AAgIlE;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDzE"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Generate benchmark report command
3
+ */
4
+ import * as fs from 'fs';
5
+ import * as path from 'path';
6
+ import { SqliteStorage, DEFAULT_DB_PATH } from '../../storage/sqlite-storage.js';
7
+ import { ConsoleReporter } from '../../reporters/console-reporter.js';
8
+ import { MarkdownReporter } from '../../reporters/markdown-reporter.js';
9
+ import { formatMs } from '../../runner/timing.js';
10
+ /**
11
+ * Find the project root
12
+ */
13
+ function findProjectRoot() {
14
+ let dir = process.cwd();
15
+ while (dir !== path.dirname(dir)) {
16
+ const pkgPath = path.join(dir, 'package.json');
17
+ if (fs.existsSync(pkgPath)) {
18
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
19
+ if (pkg.workspaces || fs.existsSync(path.join(dir, 'pnpm-workspace.yaml'))) {
20
+ return dir;
21
+ }
22
+ }
23
+ dir = path.dirname(dir);
24
+ }
25
+ return process.cwd();
26
+ }
27
+ /**
28
+ * Generate a console report from runs
29
+ */
30
+ function generateConsoleReport(runs) {
31
+ const reporter = new ConsoleReporter();
32
+ if (runs.length === 0) {
33
+ console.log('No benchmark runs found.');
34
+ return;
35
+ }
36
+ console.log(`\n=== Benchmark History (${runs.length} runs) ===\n`);
37
+ for (const run of runs) {
38
+ console.log(`Run: ${run.id}`);
39
+ console.log(` Date: ${new Date(run.startTime).toLocaleString()}`);
40
+ if (run.git) {
41
+ console.log(` Commit: ${run.git.commitHash.substring(0, 7)} (${run.git.branch})`);
42
+ }
43
+ console.log(` Duration: ${formatMs(run.duration)}`);
44
+ console.log(` Benchmarks: ${run.measurements.length}`);
45
+ console.log();
46
+ }
47
+ // Show latest run details
48
+ if (runs.length > 0) {
49
+ console.log('\n=== Latest Run Details ===\n');
50
+ reporter.reportRun(runs[0]);
51
+ }
52
+ }
53
+ /**
54
+ * Generate a markdown report from runs
55
+ */
56
+ function generateMarkdownReport(runs) {
57
+ const reporter = new MarkdownReporter();
58
+ const lines = [];
59
+ lines.push('# Benchmark Report');
60
+ lines.push('');
61
+ lines.push(`Generated: ${new Date().toLocaleString()}`);
62
+ lines.push('');
63
+ if (runs.length === 0) {
64
+ lines.push('No benchmark runs found.');
65
+ return lines.join('\n');
66
+ }
67
+ // Summary table
68
+ lines.push('## Run History');
69
+ lines.push('');
70
+ lines.push('| Date | Commit | Branch | Duration | Benchmarks |');
71
+ lines.push('|------|--------|--------|----------|------------|');
72
+ for (const run of runs) {
73
+ const date = new Date(run.startTime).toLocaleDateString();
74
+ const commit = run.git ? `\`${run.git.commitHash.substring(0, 7)}\`` : '-';
75
+ const branch = run.git?.branch || '-';
76
+ lines.push(`| ${date} | ${commit} | ${branch} | ${formatMs(run.duration)} | ${run.measurements.length} |`);
77
+ }
78
+ lines.push('');
79
+ // Latest run details
80
+ if (runs.length > 0) {
81
+ lines.push('## Latest Run');
82
+ lines.push('');
83
+ lines.push(reporter.reportRun(runs[0]));
84
+ }
85
+ return lines.join('\n');
86
+ }
87
+ /**
88
+ * Generate a JSON report from runs
89
+ */
90
+ function generateJsonReport(runs) {
91
+ return JSON.stringify({
92
+ generated: new Date().toISOString(),
93
+ runCount: runs.length,
94
+ runs: runs.map((run) => ({
95
+ id: run.id,
96
+ startTime: run.startTime,
97
+ endTime: run.endTime,
98
+ duration: run.duration,
99
+ git: run.git,
100
+ environment: run.environment,
101
+ measurements: run.measurements.map((m) => ({
102
+ name: m.name,
103
+ package: m.package,
104
+ function: m.function,
105
+ mean: m.timing.mean,
106
+ median: m.timing.median,
107
+ p95: m.timing.p95,
108
+ iterations: m.iterations,
109
+ })),
110
+ })),
111
+ }, null, 2);
112
+ }
113
+ /**
114
+ * Run the report command
115
+ */
116
+ export async function reportCommand(options) {
117
+ const projectRoot = findProjectRoot();
118
+ const dbPath = path.join(projectRoot, DEFAULT_DB_PATH);
119
+ if (!fs.existsSync(dbPath)) {
120
+ console.error('No benchmark database found.');
121
+ console.error('Run benchmarks first to generate data.');
122
+ process.exit(1);
123
+ }
124
+ const sqliteStorage = new SqliteStorage(dbPath);
125
+ const runs = sqliteStorage.getRecentRuns(options.history ?? 10);
126
+ sqliteStorage.close();
127
+ const format = options.format || 'console';
128
+ let output;
129
+ switch (format) {
130
+ case 'console':
131
+ generateConsoleReport(runs);
132
+ output = '';
133
+ break;
134
+ case 'markdown':
135
+ output = generateMarkdownReport(runs);
136
+ console.log(output);
137
+ break;
138
+ case 'json':
139
+ output = generateJsonReport(runs);
140
+ console.log(output);
141
+ break;
142
+ default:
143
+ output = '';
144
+ }
145
+ // Write to file if specified
146
+ if (options.output && output) {
147
+ const outputPath = path.isAbsolute(options.output)
148
+ ? options.output
149
+ : path.join(projectRoot, options.output);
150
+ const outputDir = path.dirname(outputPath);
151
+ if (!fs.existsSync(outputDir)) {
152
+ fs.mkdirSync(outputDir, { recursive: true });
153
+ }
154
+ fs.writeFileSync(outputPath, output);
155
+ console.log(`\nReport written to: ${outputPath}`);
156
+ }
157
+ }
158
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/cli/commands/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Run benchmarks command
3
+ */
4
+ import type { RunOptions } from '../../types.js';
5
+ /**
6
+ * Run the benchmark command
7
+ */
8
+ export declare function runCommand(options: RunOptions): Promise<void>;
9
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAqBjD;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA+CnE"}