modestbench 0.0.3 → 0.2.0
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/CHANGELOG.md +26 -0
- package/README.md +39 -31
- package/dist/bootstrap.cjs +10 -12
- package/dist/bootstrap.cjs.map +1 -1
- package/dist/bootstrap.d.cts.map +1 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +5 -7
- package/dist/bootstrap.js.map +1 -1
- package/dist/cli/commands/history.cjs +108 -265
- package/dist/cli/commands/history.cjs.map +1 -1
- package/dist/cli/commands/history.d.cts +75 -12
- package/dist/cli/commands/history.d.cts.map +1 -1
- package/dist/cli/commands/history.d.ts +75 -12
- package/dist/cli/commands/history.d.ts.map +1 -1
- package/dist/cli/commands/history.js +105 -267
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/init.cjs +5 -4
- package/dist/cli/commands/init.cjs.map +1 -1
- package/dist/cli/commands/init.d.cts.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +5 -4
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/run.cjs +32 -9
- package/dist/cli/commands/run.cjs.map +1 -1
- package/dist/cli/commands/run.d.cts +1 -0
- package/dist/cli/commands/run.d.cts.map +1 -1
- package/dist/cli/commands/run.d.ts +1 -0
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +32 -9
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/index.cjs +336 -103
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +1 -2
- package/dist/cli/index.d.cts.map +1 -1
- package/dist/cli/index.d.ts +1 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +332 -99
- package/dist/cli/index.js.map +1 -1
- package/dist/constants.cjs +53 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +36 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.ts +36 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +52 -0
- package/dist/constants.js.map +1 -1
- package/dist/core/engine.cjs +23 -43
- package/dist/core/engine.cjs.map +1 -1
- package/dist/core/engine.d.cts +4 -3
- package/dist/core/engine.d.cts.map +1 -1
- package/dist/core/engine.d.ts +4 -3
- package/dist/core/engine.d.ts.map +1 -1
- package/dist/core/engine.js +23 -43
- package/dist/core/engine.js.map +1 -1
- package/dist/core/engines/accurate-engine.cjs +2 -1
- package/dist/core/engines/accurate-engine.cjs.map +1 -1
- package/dist/core/engines/accurate-engine.d.cts.map +1 -1
- package/dist/core/engines/accurate-engine.d.ts.map +1 -1
- package/dist/core/engines/accurate-engine.js +2 -1
- package/dist/core/engines/accurate-engine.js.map +1 -1
- package/dist/core/engines/tinybench-engine.cjs +6 -5
- package/dist/core/engines/tinybench-engine.cjs.map +1 -1
- package/dist/core/engines/tinybench-engine.d.cts.map +1 -1
- package/dist/core/engines/tinybench-engine.d.ts.map +1 -1
- package/dist/core/engines/tinybench-engine.js +6 -5
- package/dist/core/engines/tinybench-engine.js.map +1 -1
- package/dist/core/output-path-resolver.cjs +34 -0
- package/dist/core/output-path-resolver.cjs.map +1 -0
- package/dist/core/output-path-resolver.d.cts +10 -0
- package/dist/core/output-path-resolver.d.cts.map +1 -0
- package/dist/core/output-path-resolver.d.ts +10 -0
- package/dist/core/output-path-resolver.d.ts.map +1 -0
- package/dist/core/output-path-resolver.js +30 -0
- package/dist/core/output-path-resolver.js.map +1 -0
- package/dist/errors/base.cjs +130 -0
- package/dist/errors/base.cjs.map +1 -0
- package/dist/errors/base.d.cts +97 -0
- package/dist/errors/base.d.cts.map +1 -0
- package/dist/errors/base.d.ts +97 -0
- package/dist/errors/base.d.ts.map +1 -0
- package/dist/errors/base.js +124 -0
- package/dist/errors/base.js.map +1 -0
- package/dist/errors/cli.cjs +58 -0
- package/dist/errors/cli.cjs.map +1 -0
- package/dist/errors/cli.d.cts +44 -0
- package/dist/errors/cli.d.cts.map +1 -0
- package/dist/errors/cli.d.ts +44 -0
- package/dist/errors/cli.d.ts.map +1 -0
- package/dist/errors/cli.js +52 -0
- package/dist/errors/cli.js.map +1 -0
- package/dist/errors/configuration.cjs +48 -0
- package/dist/errors/configuration.cjs.map +1 -0
- package/dist/errors/configuration.d.cts +41 -0
- package/dist/errors/configuration.d.cts.map +1 -0
- package/dist/errors/configuration.d.ts +41 -0
- package/dist/errors/configuration.d.ts.map +1 -0
- package/dist/errors/configuration.js +41 -0
- package/dist/errors/configuration.js.map +1 -0
- package/dist/errors/execution.cjs +65 -0
- package/dist/errors/execution.cjs.map +1 -0
- package/dist/errors/execution.d.cts +56 -0
- package/dist/errors/execution.d.cts.map +1 -0
- package/dist/errors/execution.d.ts +56 -0
- package/dist/errors/execution.d.ts.map +1 -0
- package/dist/errors/execution.js +56 -0
- package/dist/errors/execution.js.map +1 -0
- package/dist/errors/file.cjs +56 -0
- package/dist/errors/file.cjs.map +1 -0
- package/dist/errors/file.d.cts +48 -0
- package/dist/errors/file.d.cts.map +1 -0
- package/dist/errors/file.d.ts +48 -0
- package/dist/errors/file.d.ts.map +1 -0
- package/dist/errors/file.js +48 -0
- package/dist/errors/file.js.map +1 -0
- package/dist/errors/index.cjs +59 -0
- package/dist/errors/index.cjs.map +1 -0
- package/dist/errors/index.d.cts +16 -0
- package/dist/errors/index.d.cts.map +1 -0
- package/dist/errors/index.d.ts +16 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +24 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/reporter.cjs +38 -0
- package/dist/errors/reporter.cjs.map +1 -0
- package/dist/errors/reporter.d.cts +32 -0
- package/dist/errors/reporter.d.cts.map +1 -0
- package/dist/errors/reporter.d.ts +32 -0
- package/dist/errors/reporter.d.ts.map +1 -0
- package/dist/errors/reporter.js +32 -0
- package/dist/errors/reporter.js.map +1 -0
- package/dist/errors/storage.cjs +55 -0
- package/dist/errors/storage.cjs.map +1 -0
- package/dist/errors/storage.d.cts +47 -0
- package/dist/errors/storage.d.cts.map +1 -0
- package/dist/errors/storage.d.ts +47 -0
- package/dist/errors/storage.d.ts.map +1 -0
- package/dist/errors/storage.js +47 -0
- package/dist/errors/storage.js.map +1 -0
- package/dist/errors/validation.cjs +38 -0
- package/dist/errors/validation.cjs.map +1 -0
- package/dist/errors/validation.d.cts +32 -0
- package/dist/errors/validation.d.cts.map +1 -0
- package/dist/errors/validation.d.ts +32 -0
- package/dist/errors/validation.d.ts.map +1 -0
- package/dist/errors/validation.js +32 -0
- package/dist/errors/validation.js.map +1 -0
- package/dist/formatters/history/base.cjs +9 -0
- package/dist/formatters/history/base.cjs.map +1 -0
- package/dist/formatters/history/base.d.cts +26 -0
- package/dist/formatters/history/base.d.cts.map +1 -0
- package/dist/formatters/history/base.d.ts +26 -0
- package/dist/formatters/history/base.d.ts.map +1 -0
- package/dist/formatters/history/base.js +8 -0
- package/dist/formatters/history/base.js.map +1 -0
- package/dist/formatters/history/compare.cjs +127 -0
- package/dist/formatters/history/compare.cjs.map +1 -0
- package/dist/formatters/history/compare.d.cts +21 -0
- package/dist/formatters/history/compare.d.cts.map +1 -0
- package/dist/formatters/history/compare.d.ts +21 -0
- package/dist/formatters/history/compare.d.ts.map +1 -0
- package/dist/formatters/history/compare.js +123 -0
- package/dist/formatters/history/compare.js.map +1 -0
- package/dist/formatters/history/list.cjs +74 -0
- package/dist/formatters/history/list.cjs.map +1 -0
- package/dist/formatters/history/list.d.cts +25 -0
- package/dist/formatters/history/list.d.cts.map +1 -0
- package/dist/formatters/history/list.d.ts +25 -0
- package/dist/formatters/history/list.d.ts.map +1 -0
- package/dist/formatters/history/list.js +70 -0
- package/dist/formatters/history/list.js.map +1 -0
- package/dist/formatters/history/show.cjs +98 -0
- package/dist/formatters/history/show.cjs.map +1 -0
- package/dist/formatters/history/show.d.cts +21 -0
- package/dist/formatters/history/show.d.cts.map +1 -0
- package/dist/formatters/history/show.d.ts +21 -0
- package/dist/formatters/history/show.d.ts.map +1 -0
- package/dist/formatters/history/show.js +94 -0
- package/dist/formatters/history/show.js.map +1 -0
- package/dist/formatters/history/trends.cjs +194 -0
- package/dist/formatters/history/trends.cjs.map +1 -0
- package/dist/formatters/history/trends.d.cts +22 -0
- package/dist/formatters/history/trends.d.cts.map +1 -0
- package/dist/formatters/history/trends.d.ts +22 -0
- package/dist/formatters/history/trends.d.ts.map +1 -0
- package/dist/formatters/history/trends.js +190 -0
- package/dist/formatters/history/trends.js.map +1 -0
- package/dist/formatters/history/visualization.cjs +79 -0
- package/dist/formatters/history/visualization.cjs.map +1 -0
- package/dist/formatters/history/visualization.d.cts +24 -0
- package/dist/formatters/history/visualization.d.cts.map +1 -0
- package/dist/formatters/history/visualization.d.ts +24 -0
- package/dist/formatters/history/visualization.d.ts.map +1 -0
- package/dist/formatters/history/visualization.js +74 -0
- package/dist/formatters/history/visualization.js.map +1 -0
- package/dist/index.cjs +17 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -11
- package/dist/index.js.map +1 -1
- package/dist/reporters/csv.cjs +5 -4
- package/dist/reporters/csv.cjs.map +1 -1
- package/dist/reporters/csv.d.cts +1 -1
- package/dist/reporters/csv.d.cts.map +1 -1
- package/dist/reporters/csv.d.ts +1 -1
- package/dist/reporters/csv.d.ts.map +1 -1
- package/dist/reporters/csv.js +4 -3
- package/dist/reporters/csv.js.map +1 -1
- package/dist/reporters/human.cjs +24 -62
- package/dist/reporters/human.cjs.map +1 -1
- package/dist/reporters/human.d.cts +1 -1
- package/dist/reporters/human.d.cts.map +1 -1
- package/dist/reporters/human.d.ts +1 -1
- package/dist/reporters/human.d.ts.map +1 -1
- package/dist/reporters/human.js +3 -41
- package/dist/reporters/human.js.map +1 -1
- package/dist/reporters/json.cjs +5 -4
- package/dist/reporters/json.cjs.map +1 -1
- package/dist/reporters/json.d.cts +1 -1
- package/dist/reporters/json.d.cts.map +1 -1
- package/dist/reporters/json.d.ts +1 -1
- package/dist/reporters/json.d.ts.map +1 -1
- package/dist/reporters/json.js +4 -3
- package/dist/reporters/json.js.map +1 -1
- package/dist/reporters/simple.cjs +3 -3
- package/dist/reporters/simple.cjs.map +1 -1
- package/dist/reporters/simple.d.cts +1 -1
- package/dist/reporters/simple.d.cts.map +1 -1
- package/dist/reporters/simple.d.ts +1 -1
- package/dist/reporters/simple.d.ts.map +1 -1
- package/dist/reporters/simple.js +2 -2
- package/dist/reporters/simple.js.map +1 -1
- package/dist/{config/manager.cjs → services/config-manager.cjs} +10 -4
- package/dist/services/config-manager.cjs.map +1 -0
- package/dist/{config/manager.d.cts → services/config-manager.d.cts} +1 -1
- package/dist/services/config-manager.d.cts.map +1 -0
- package/dist/{config/manager.d.ts → services/config-manager.d.ts} +1 -1
- package/dist/services/config-manager.d.ts.map +1 -0
- package/dist/{config/manager.js → services/config-manager.js} +10 -4
- package/dist/services/config-manager.js.map +1 -0
- package/dist/{core/loader.cjs → services/file-loader.cjs} +18 -7
- package/dist/services/file-loader.cjs.map +1 -0
- package/dist/{core/loader.d.cts → services/file-loader.d.cts} +1 -1
- package/dist/services/file-loader.d.cts.map +1 -0
- package/dist/{core/loader.d.ts → services/file-loader.d.ts} +1 -1
- package/dist/services/file-loader.d.ts.map +1 -0
- package/dist/{core/loader.js → services/file-loader.js} +18 -7
- package/dist/services/file-loader.js.map +1 -0
- package/dist/services/history/comparison.cjs +124 -0
- package/dist/services/history/comparison.cjs.map +1 -0
- package/dist/services/history/comparison.d.cts +18 -0
- package/dist/services/history/comparison.d.cts.map +1 -0
- package/dist/services/history/comparison.d.ts +18 -0
- package/dist/services/history/comparison.d.ts.map +1 -0
- package/dist/services/history/comparison.js +120 -0
- package/dist/services/history/comparison.js.map +1 -0
- package/dist/services/history/models.cjs +9 -0
- package/dist/services/history/models.cjs.map +1 -0
- package/dist/services/history/models.d.cts +139 -0
- package/dist/services/history/models.d.cts.map +1 -0
- package/dist/services/history/models.d.ts +139 -0
- package/dist/services/history/models.d.ts.map +1 -0
- package/dist/services/history/models.js +8 -0
- package/dist/services/history/models.js.map +1 -0
- package/dist/services/history/query.cjs +97 -0
- package/dist/services/history/query.cjs.map +1 -0
- package/dist/services/history/query.d.cts +38 -0
- package/dist/services/history/query.d.cts.map +1 -0
- package/dist/services/history/query.d.ts +38 -0
- package/dist/services/history/query.d.ts.map +1 -0
- package/dist/services/history/query.js +92 -0
- package/dist/services/history/query.js.map +1 -0
- package/dist/services/history/trend-analysis.cjs +187 -0
- package/dist/services/history/trend-analysis.cjs.map +1 -0
- package/dist/services/history/trend-analysis.d.cts +34 -0
- package/dist/services/history/trend-analysis.d.cts.map +1 -0
- package/dist/services/history/trend-analysis.d.ts +34 -0
- package/dist/services/history/trend-analysis.d.ts.map +1 -0
- package/dist/services/history/trend-analysis.js +179 -0
- package/dist/services/history/trend-analysis.js.map +1 -0
- package/dist/{storage/history.cjs → services/history-storage.cjs} +33 -12
- package/dist/services/history-storage.cjs.map +1 -0
- package/dist/{storage/history.d.cts → services/history-storage.d.cts} +1 -1
- package/dist/services/history-storage.d.cts.map +1 -0
- package/dist/{storage/history.d.ts → services/history-storage.d.ts} +1 -1
- package/dist/services/history-storage.d.ts.map +1 -0
- package/dist/{storage/history.js → services/history-storage.js} +33 -12
- package/dist/services/history-storage.js.map +1 -0
- package/dist/{progress/manager.cjs → services/progress-manager.cjs} +1 -1
- package/dist/services/progress-manager.cjs.map +1 -0
- package/dist/{progress/manager.d.cts → services/progress-manager.d.cts} +1 -1
- package/dist/services/progress-manager.d.cts.map +1 -0
- package/dist/{progress/manager.d.ts → services/progress-manager.d.ts} +1 -1
- package/dist/services/progress-manager.d.ts.map +1 -0
- package/dist/{progress/manager.js → services/progress-manager.js} +1 -1
- package/dist/services/progress-manager.js.map +1 -0
- package/dist/{reporters/registry.cjs → services/reporter-registry.cjs} +4 -3
- package/dist/services/reporter-registry.cjs.map +1 -0
- package/dist/{reporters/registry.d.cts → services/reporter-registry.d.cts} +1 -1
- package/dist/services/reporter-registry.d.cts.map +1 -0
- package/dist/{reporters/registry.d.ts → services/reporter-registry.d.ts} +1 -1
- package/dist/services/reporter-registry.d.ts.map +1 -0
- package/dist/{reporters/registry.js → services/reporter-registry.js} +4 -3
- package/dist/services/reporter-registry.js.map +1 -0
- package/dist/types/cli.d.cts +3 -0
- package/dist/types/cli.d.cts.map +1 -1
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/interfaces.d.cts +1 -34
- package/dist/types/interfaces.d.cts.map +1 -1
- package/dist/types/interfaces.d.ts +1 -34
- package/dist/types/interfaces.d.ts.map +1 -1
- package/dist/utils/ansi.cjs +61 -0
- package/dist/utils/ansi.cjs.map +1 -0
- package/dist/utils/ansi.d.cts +53 -0
- package/dist/utils/ansi.d.cts.map +1 -0
- package/dist/utils/ansi.d.ts +53 -0
- package/dist/utils/ansi.d.ts.map +1 -0
- package/dist/utils/ansi.js +57 -0
- package/dist/utils/ansi.js.map +1 -0
- package/package.json +10 -8
- package/src/bootstrap.ts +5 -7
- package/src/cli/commands/history.ts +195 -341
- package/src/cli/commands/init.ts +14 -4
- package/src/cli/commands/run.ts +52 -7
- package/src/cli/index.ts +393 -119
- package/src/constants.ts +60 -0
- package/src/core/engine.ts +40 -48
- package/src/core/engines/accurate-engine.ts +4 -1
- package/src/core/engines/tinybench-engine.ts +12 -5
- package/src/core/output-path-resolver.ts +38 -0
- package/src/errors/base.ts +152 -0
- package/src/errors/cli.ts +59 -0
- package/src/errors/configuration.ts +45 -0
- package/src/errors/execution.ts +62 -0
- package/src/errors/file.ts +53 -0
- package/src/errors/index.ts +71 -0
- package/src/errors/reporter.ts +35 -0
- package/src/errors/storage.ts +52 -0
- package/src/errors/validation.ts +35 -0
- package/src/formatters/history/base.ts +28 -0
- package/src/formatters/history/compare.ts +186 -0
- package/src/formatters/history/list.ts +101 -0
- package/src/formatters/history/show.ts +155 -0
- package/src/formatters/history/trends.ts +281 -0
- package/src/formatters/history/visualization.ts +93 -0
- package/src/index.ts +10 -14
- package/src/reporters/csv.ts +5 -3
- package/src/reporters/human.ts +3 -43
- package/src/reporters/json.ts +5 -3
- package/src/reporters/simple.ts +2 -2
- package/src/{config/manager.ts → services/config-manager.ts} +13 -3
- package/src/{core/loader.ts → services/file-loader.ts} +28 -6
- package/src/services/history/comparison.ts +130 -0
- package/src/services/history/models.ts +148 -0
- package/src/services/history/query.ts +116 -0
- package/src/services/history/trend-analysis.ts +238 -0
- package/src/{storage/history.ts → services/history-storage.ts} +58 -11
- package/src/{reporters/registry.ts → services/reporter-registry.ts} +9 -2
- package/src/types/cli.ts +3 -0
- package/src/types/interfaces.ts +0 -43
- package/src/utils/ansi.ts +59 -0
- package/dist/config/manager.cjs.map +0 -1
- package/dist/config/manager.d.cts.map +0 -1
- package/dist/config/manager.d.ts.map +0 -1
- package/dist/config/manager.js.map +0 -1
- package/dist/core/error-manager.cjs +0 -303
- package/dist/core/error-manager.cjs.map +0 -1
- package/dist/core/error-manager.d.cts +0 -77
- package/dist/core/error-manager.d.cts.map +0 -1
- package/dist/core/error-manager.d.ts +0 -77
- package/dist/core/error-manager.d.ts.map +0 -1
- package/dist/core/error-manager.js +0 -299
- package/dist/core/error-manager.js.map +0 -1
- package/dist/core/loader.cjs.map +0 -1
- package/dist/core/loader.d.cts.map +0 -1
- package/dist/core/loader.d.ts.map +0 -1
- package/dist/core/loader.js.map +0 -1
- package/dist/progress/manager.cjs.map +0 -1
- package/dist/progress/manager.d.cts.map +0 -1
- package/dist/progress/manager.d.ts.map +0 -1
- package/dist/progress/manager.js.map +0 -1
- package/dist/reporters/registry.cjs.map +0 -1
- package/dist/reporters/registry.d.cts.map +0 -1
- package/dist/reporters/registry.d.ts.map +0 -1
- package/dist/reporters/registry.js.map +0 -1
- package/dist/storage/history.cjs.map +0 -1
- package/dist/storage/history.d.cts.map +0 -1
- package/dist/storage/history.d.ts.map +0 -1
- package/dist/storage/history.js.map +0 -1
- package/src/core/error-manager.ts +0 -372
- /package/src/{progress/manager.ts → services/progress-manager.ts} +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModestBench Error Classes
|
|
3
|
+
*
|
|
4
|
+
* Custom error classes for structured error handling throughout ModestBench.
|
|
5
|
+
* All errors extend ModestBenchError and include error codes and documentation
|
|
6
|
+
* URLs.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Base error classes and utilities
|
|
10
|
+
export {
|
|
11
|
+
isModestBenchError,
|
|
12
|
+
ModestBenchAggregateError,
|
|
13
|
+
ModestBenchError,
|
|
14
|
+
} from './base.js';
|
|
15
|
+
|
|
16
|
+
// CLI errors
|
|
17
|
+
export {
|
|
18
|
+
InvalidArgumentError,
|
|
19
|
+
InvalidDateFormatError,
|
|
20
|
+
UnknownError,
|
|
21
|
+
} from './cli.js';
|
|
22
|
+
|
|
23
|
+
// Configuration errors
|
|
24
|
+
export {
|
|
25
|
+
ConfigLoadError,
|
|
26
|
+
ConfigNotFoundError,
|
|
27
|
+
ConfigValidationError,
|
|
28
|
+
UnsupportedConfigFormatError,
|
|
29
|
+
} from './configuration.js';
|
|
30
|
+
|
|
31
|
+
// Execution errors
|
|
32
|
+
export {
|
|
33
|
+
BenchmarkExecutionError,
|
|
34
|
+
OperationTooFastError,
|
|
35
|
+
SetupError,
|
|
36
|
+
TaskExecutionError,
|
|
37
|
+
TeardownError,
|
|
38
|
+
TimeoutError,
|
|
39
|
+
} from './execution.js';
|
|
40
|
+
|
|
41
|
+
// File errors
|
|
42
|
+
export {
|
|
43
|
+
FileDiscoveryError,
|
|
44
|
+
FileLoadError,
|
|
45
|
+
FileNotFoundError,
|
|
46
|
+
FilePermissionError,
|
|
47
|
+
UnsupportedFileExtensionError,
|
|
48
|
+
} from './file.js';
|
|
49
|
+
|
|
50
|
+
// Reporter errors
|
|
51
|
+
export {
|
|
52
|
+
ReporterAlreadyRegisteredError,
|
|
53
|
+
ReporterOutputError,
|
|
54
|
+
UnknownReporterError,
|
|
55
|
+
} from './reporter.js';
|
|
56
|
+
|
|
57
|
+
// Storage errors
|
|
58
|
+
export {
|
|
59
|
+
StorageCorruptionError,
|
|
60
|
+
StorageError,
|
|
61
|
+
StorageIndexError,
|
|
62
|
+
StorageSpaceError,
|
|
63
|
+
UnsupportedExportFormatError,
|
|
64
|
+
} from './storage.js';
|
|
65
|
+
|
|
66
|
+
// Validation errors
|
|
67
|
+
export {
|
|
68
|
+
SchemaValidationError,
|
|
69
|
+
StructureValidationError,
|
|
70
|
+
TypeValidationError,
|
|
71
|
+
} from './validation.js';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reporter-related errors
|
|
3
|
+
*
|
|
4
|
+
* Errors that occur during reporter operations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ModestBenchError } from './base.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Reporter already registered
|
|
11
|
+
*
|
|
12
|
+
* Thrown when attempting to register a reporter with a name that is already in
|
|
13
|
+
* use.
|
|
14
|
+
*/
|
|
15
|
+
export class ReporterAlreadyRegisteredError extends ModestBenchError {
|
|
16
|
+
readonly code = 'ERR_MB_REPORTER_ALREADY_REGISTERED';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Reporter output failed
|
|
21
|
+
*
|
|
22
|
+
* Thrown when a reporter fails to write output.
|
|
23
|
+
*/
|
|
24
|
+
export class ReporterOutputError extends ModestBenchError {
|
|
25
|
+
readonly code = 'ERR_MB_REPORTER_OUTPUT_FAILED';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Unknown reporter
|
|
30
|
+
*
|
|
31
|
+
* Thrown when attempting to use a reporter that is not registered.
|
|
32
|
+
*/
|
|
33
|
+
export class UnknownReporterError extends ModestBenchError {
|
|
34
|
+
readonly code = 'ERR_MB_REPORTER_UNKNOWN';
|
|
35
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage-related errors
|
|
3
|
+
*
|
|
4
|
+
* Errors that occur during history storage operations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ModestBenchError } from './base.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Storage data corruption
|
|
11
|
+
*
|
|
12
|
+
* Thrown when stored data is found to be corrupted or invalid.
|
|
13
|
+
*/
|
|
14
|
+
export class StorageCorruptionError extends ModestBenchError {
|
|
15
|
+
readonly code = 'ERR_MB_STORAGE_CORRUPTION';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Storage operation failed
|
|
20
|
+
*
|
|
21
|
+
* Thrown when a general storage operation fails.
|
|
22
|
+
*/
|
|
23
|
+
export class StorageError extends ModestBenchError {
|
|
24
|
+
readonly code = 'ERR_MB_STORAGE_FAILED';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Storage index corruption
|
|
29
|
+
*
|
|
30
|
+
* Thrown when the storage index is corrupted or cannot be read.
|
|
31
|
+
*/
|
|
32
|
+
export class StorageIndexError extends ModestBenchError {
|
|
33
|
+
readonly code = 'ERR_MB_STORAGE_INDEX_CORRUPTION';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Insufficient storage space
|
|
38
|
+
*
|
|
39
|
+
* Thrown when there is insufficient disk space for storage operations.
|
|
40
|
+
*/
|
|
41
|
+
export class StorageSpaceError extends ModestBenchError {
|
|
42
|
+
readonly code = 'ERR_MB_STORAGE_INSUFFICIENT_SPACE';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Unsupported export format
|
|
47
|
+
*
|
|
48
|
+
* Thrown when attempting to export data in an unsupported format.
|
|
49
|
+
*/
|
|
50
|
+
export class UnsupportedExportFormatError extends ModestBenchError {
|
|
51
|
+
readonly code = 'ERR_MB_STORAGE_EXPORT_UNSUPPORTED';
|
|
52
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation-related errors
|
|
3
|
+
*
|
|
4
|
+
* Errors that occur during benchmark file structure and data validation.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ModestBenchError } from './base.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Schema validation failed
|
|
11
|
+
*
|
|
12
|
+
* Thrown when data fails to validate against a Zod schema or other schema
|
|
13
|
+
* validation.
|
|
14
|
+
*/
|
|
15
|
+
export class SchemaValidationError extends ModestBenchError {
|
|
16
|
+
readonly code = 'ERR_MB_VALIDATION_SCHEMA_FAILED';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Invalid benchmark structure
|
|
21
|
+
*
|
|
22
|
+
* Thrown when a benchmark file has an invalid or unexpected structure.
|
|
23
|
+
*/
|
|
24
|
+
export class StructureValidationError extends ModestBenchError {
|
|
25
|
+
readonly code = 'ERR_MB_VALIDATION_STRUCTURE_INVALID';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Type validation failed
|
|
30
|
+
*
|
|
31
|
+
* Thrown when data fails type validation checks.
|
|
32
|
+
*/
|
|
33
|
+
export class TypeValidationError extends ModestBenchError {
|
|
34
|
+
readonly code = 'ERR_MB_VALIDATION_TYPE_FAILED';
|
|
35
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Formatter Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines the contract for history command formatters. Each formatter
|
|
5
|
+
* transforms processed data into human-readable or machine-readable output.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Formatter interface for history command output
|
|
10
|
+
*
|
|
11
|
+
* @template TData - The data type this formatter accepts
|
|
12
|
+
*/
|
|
13
|
+
export interface HistoryFormatter<TData> {
|
|
14
|
+
/**
|
|
15
|
+
* Format data as CSV (optional, not all commands support CSV)
|
|
16
|
+
*/
|
|
17
|
+
formatCsv?(data: TData): string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Format data for human-readable terminal output
|
|
21
|
+
*/
|
|
22
|
+
formatHuman(data: TData): string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Format data as JSON
|
|
26
|
+
*/
|
|
27
|
+
formatJson(data: TData): string;
|
|
28
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare Formatter
|
|
3
|
+
*
|
|
4
|
+
* Formats benchmark run comparison results in human and JSON formats.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { CompareResult } from '../../services/history/models.js';
|
|
8
|
+
import type { HistoryFormatter } from './base.js';
|
|
9
|
+
|
|
10
|
+
import { colorize } from '../../utils/ansi.js';
|
|
11
|
+
import { ansiChars } from '../../utils/ansi.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Formatter for history compare command
|
|
15
|
+
*/
|
|
16
|
+
export class HistoryCompareFormatter
|
|
17
|
+
implements HistoryFormatter<CompareResult>
|
|
18
|
+
{
|
|
19
|
+
/**
|
|
20
|
+
* Format as human-readable comparison
|
|
21
|
+
*/
|
|
22
|
+
formatHuman(data: CompareResult): string {
|
|
23
|
+
const lines: string[] = [];
|
|
24
|
+
|
|
25
|
+
lines.push(colorize('brightMagenta', colorize('bold', 'Comparing runs:')));
|
|
26
|
+
lines.push(
|
|
27
|
+
` ${colorize('brightCyan', ansiChars.bullet)} ${colorize('brightWhite', colorize('bold', 'Run 1'))} ${colorize('dim', data.run1.id)} (${colorize('white', data.run1.startTime.toLocaleString())})`,
|
|
28
|
+
);
|
|
29
|
+
lines.push(
|
|
30
|
+
` ${colorize('brightCyan', ansiChars.bullet)} ${colorize('brightWhite', colorize('bold', 'Run 2'))} ${colorize('dim', data.run2.id)} (${colorize('white', data.run2.startTime.toLocaleString())})`,
|
|
31
|
+
);
|
|
32
|
+
lines.push('');
|
|
33
|
+
|
|
34
|
+
lines.push(colorize('cyan', 'Summary comparison:'));
|
|
35
|
+
lines.push('');
|
|
36
|
+
lines.push(
|
|
37
|
+
` ${colorize('dim', ansiChars.smallSquare)} Files: ${colorize('brightWhite', String(data.run1.summary.totalFiles))} vs ${colorize('brightWhite', String(data.run2.summary.totalFiles))}`,
|
|
38
|
+
);
|
|
39
|
+
lines.push(
|
|
40
|
+
` ${colorize('dim', ansiChars.smallSquare)} Tasks: ${colorize('brightWhite', String(data.run1.summary.totalTasks))} vs ${colorize('brightWhite', String(data.run2.summary.totalTasks))}`,
|
|
41
|
+
);
|
|
42
|
+
lines.push(
|
|
43
|
+
` ${colorize('dim', ansiChars.smallSquare)} Passed: ${colorize('brightCyan', String(data.run1.summary.passedTasks))} vs ${colorize('brightCyan', String(data.run2.summary.passedTasks))}`,
|
|
44
|
+
);
|
|
45
|
+
lines.push(
|
|
46
|
+
` ${colorize('dim', ansiChars.smallSquare)} Failed: ${colorize('brightRed', colorize('bold', String(data.run1.summary.failedTasks)))} vs ${colorize('brightRed', colorize('bold', String(data.run2.summary.failedTasks)))}`,
|
|
47
|
+
);
|
|
48
|
+
lines.push('');
|
|
49
|
+
|
|
50
|
+
// Detailed task comparison
|
|
51
|
+
if (data.tasksInBoth.length > 0) {
|
|
52
|
+
lines.push(colorize('cyan', 'Task-by-task comparison:'));
|
|
53
|
+
lines.push('');
|
|
54
|
+
|
|
55
|
+
for (const comparison of data.tasksInBoth) {
|
|
56
|
+
const mean1 = comparison.run1!.mean / 1000000; // Convert to ms
|
|
57
|
+
const mean2 = comparison.run2!.mean / 1000000;
|
|
58
|
+
const changeSign = comparison.percentChange >= 0 ? '+' : '';
|
|
59
|
+
const changeStr = `${changeSign}${comparison.percentChange.toFixed(1)}%`;
|
|
60
|
+
|
|
61
|
+
lines.push(
|
|
62
|
+
` ${colorize('brightWhite', `${comparison.suite} › ${comparison.task}`)}`,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// Mean - highlight higher (slower/worse) number
|
|
66
|
+
const meanHigher = mean2 > mean1;
|
|
67
|
+
const mean1Str = meanHigher
|
|
68
|
+
? colorize('magenta', `${mean1.toFixed(3)}ms`)
|
|
69
|
+
: colorize('brightMagenta', `${mean1.toFixed(3)}ms`);
|
|
70
|
+
const mean2Str = meanHigher
|
|
71
|
+
? colorize('brightMagenta', `${mean2.toFixed(3)}ms`)
|
|
72
|
+
: colorize('magenta', `${mean2.toFixed(3)}ms`);
|
|
73
|
+
lines.push(
|
|
74
|
+
` ${colorize('dim', ansiChars.bullet)} ${colorize('white', 'Mean:')} ${mean1Str} ${colorize('dim', '→')} ${mean2Str} ${colorize('dim', `(${colorize('white', changeStr)}`)}`,
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// Min - highlight higher number
|
|
78
|
+
const min1 = comparison.run1!.min / 1000000;
|
|
79
|
+
const min2 = comparison.run2!.min / 1000000;
|
|
80
|
+
const minHigher = min2 > min1;
|
|
81
|
+
const min1Str = minHigher
|
|
82
|
+
? colorize('magenta', `${min1.toFixed(3)}ms`)
|
|
83
|
+
: colorize('brightMagenta', `${min1.toFixed(3)}ms`);
|
|
84
|
+
const min2Str = minHigher
|
|
85
|
+
? colorize('brightMagenta', `${min2.toFixed(3)}ms`)
|
|
86
|
+
: colorize('magenta', `${min2.toFixed(3)}ms`);
|
|
87
|
+
lines.push(
|
|
88
|
+
` ${colorize('dim', ansiChars.bullet)} ${colorize('white', 'Min:')} ${min1Str} ${colorize('dim', '→')} ${min2Str}`,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// Max - highlight higher number
|
|
92
|
+
const max1 = comparison.run1!.max / 1000000;
|
|
93
|
+
const max2 = comparison.run2!.max / 1000000;
|
|
94
|
+
const maxHigher = max2 > max1;
|
|
95
|
+
const max1Str = maxHigher
|
|
96
|
+
? colorize('magenta', `${max1.toFixed(3)}ms`)
|
|
97
|
+
: colorize('brightMagenta', `${max1.toFixed(3)}ms`);
|
|
98
|
+
const max2Str = maxHigher
|
|
99
|
+
? colorize('brightMagenta', `${max2.toFixed(3)}ms`)
|
|
100
|
+
: colorize('magenta', `${max2.toFixed(3)}ms`);
|
|
101
|
+
lines.push(
|
|
102
|
+
` ${colorize('dim', ansiChars.bullet)} ${colorize('white', 'Max:')} ${max1Str} ${colorize('dim', '→')} ${max2Str}`,
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// Iterations - highlight higher number
|
|
106
|
+
const iter1 = comparison.run1!.iterations;
|
|
107
|
+
const iter2 = comparison.run2!.iterations;
|
|
108
|
+
const iterHigher = iter2 > iter1;
|
|
109
|
+
const iter1Str = iterHigher
|
|
110
|
+
? colorize('brightWhite', String(iter1))
|
|
111
|
+
: colorize('bold', colorize('brightWhite', String(iter1)));
|
|
112
|
+
const iter2Str = iterHigher
|
|
113
|
+
? colorize('bold', colorize('brightWhite', String(iter2)))
|
|
114
|
+
: colorize('brightWhite', String(iter2));
|
|
115
|
+
lines.push(
|
|
116
|
+
` ${colorize('dim', ansiChars.bullet)} ${colorize('white', 'Iterations:')} ${iter1Str} ${colorize('dim', 'vs')} ${iter2Str}`,
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
// CV (Coefficient of Variation) - shows measurement consistency
|
|
120
|
+
const cv1 = comparison.run1!.cv * 100;
|
|
121
|
+
const cv2 = comparison.run2!.cv * 100;
|
|
122
|
+
const cvHigher = cv2 > cv1;
|
|
123
|
+
const cv1Str = cvHigher
|
|
124
|
+
? colorize('magenta', `${cv1.toFixed(2)}%`)
|
|
125
|
+
: colorize('brightMagenta', `${cv1.toFixed(2)}%`);
|
|
126
|
+
const cv2Str = cvHigher
|
|
127
|
+
? colorize('brightMagenta', `${cv2.toFixed(2)}%`)
|
|
128
|
+
: colorize('magenta', `${cv2.toFixed(2)}%`);
|
|
129
|
+
lines.push(
|
|
130
|
+
` ${colorize('dim', ansiChars.bullet)} ${colorize('white', 'CV:')} ${cv1Str} ${colorize('dim', '→')} ${cv2Str}`,
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
lines.push('');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (data.tasksOnlyInRun1.length > 0) {
|
|
138
|
+
lines.push(
|
|
139
|
+
colorize(
|
|
140
|
+
'cyan',
|
|
141
|
+
`Tasks only in run 1 (${data.tasksOnlyInRun1.length}):`,
|
|
142
|
+
),
|
|
143
|
+
);
|
|
144
|
+
for (const task of data.tasksOnlyInRun1) {
|
|
145
|
+
lines.push(
|
|
146
|
+
` ${colorize('dim', ansiChars.bullet)} ${colorize('brightWhite', `${task.suite} › ${task.task}`)}`,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
lines.push('');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (data.tasksOnlyInRun2.length > 0) {
|
|
153
|
+
lines.push(
|
|
154
|
+
colorize(
|
|
155
|
+
'cyan',
|
|
156
|
+
`Tasks only in run 2 (${data.tasksOnlyInRun2.length}):`,
|
|
157
|
+
),
|
|
158
|
+
);
|
|
159
|
+
for (const task of data.tasksOnlyInRun2) {
|
|
160
|
+
lines.push(
|
|
161
|
+
` ${colorize('dim', ansiChars.bullet)} ${colorize('brightWhite', `${task.suite} › ${task.task}`)}`,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
lines.push('');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return lines.join('\n');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Format as JSON
|
|
172
|
+
*/
|
|
173
|
+
formatJson(data: CompareResult): string {
|
|
174
|
+
return JSON.stringify(
|
|
175
|
+
{
|
|
176
|
+
run1: data.run1,
|
|
177
|
+
run2: data.run2,
|
|
178
|
+
taskComparisons: data.tasksInBoth,
|
|
179
|
+
tasksOnlyInRun1: data.tasksOnlyInRun1,
|
|
180
|
+
tasksOnlyInRun2: data.tasksOnlyInRun2,
|
|
181
|
+
},
|
|
182
|
+
null,
|
|
183
|
+
2,
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List Formatter
|
|
3
|
+
*
|
|
4
|
+
* Formats historical run listings in human, JSON, and CSV formats.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { HistoryListResult } from '../../services/history/models.js';
|
|
8
|
+
import type { HistoryFormatter } from './base.js';
|
|
9
|
+
|
|
10
|
+
import { ansiChars, colorize } from '../../utils/ansi.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Formatter for history list command
|
|
14
|
+
*/
|
|
15
|
+
export class HistoryListFormatter
|
|
16
|
+
implements HistoryFormatter<HistoryListResult>
|
|
17
|
+
{
|
|
18
|
+
/**
|
|
19
|
+
* Format as CSV
|
|
20
|
+
*/
|
|
21
|
+
formatCsv(data: HistoryListResult): string {
|
|
22
|
+
const lines: string[] = ['id,startTime,duration,files,tasks,passed,failed'];
|
|
23
|
+
|
|
24
|
+
for (const run of data.runs) {
|
|
25
|
+
lines.push(
|
|
26
|
+
`${run.id},${run.startTime.toISOString()},${run.duration},${run.summary.totalFiles},${run.summary.totalTasks},${run.summary.passedTasks},${run.summary.failedTasks}`,
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return lines.join('\n');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Format as human-readable list
|
|
35
|
+
*/
|
|
36
|
+
formatHuman(data: HistoryListResult): string {
|
|
37
|
+
if (data.runs.length === 0) {
|
|
38
|
+
return colorize('dim', 'No historical data found matching criteria.');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const lines: string[] = [
|
|
42
|
+
colorize('brightMagenta', colorize('bold', '\nRecent Benchmark Runs')),
|
|
43
|
+
'',
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
for (const run of data.runs) {
|
|
47
|
+
const dateStr = run.startTime.toLocaleString();
|
|
48
|
+
const durationStr = `${(run.duration / 1000).toFixed(1)}s`;
|
|
49
|
+
|
|
50
|
+
// Status with colors and symbols
|
|
51
|
+
const hasFailures = run.summary.failedTasks > 0;
|
|
52
|
+
const statusIcon = hasFailures
|
|
53
|
+
? colorize('brightRed', ansiChars.cross)
|
|
54
|
+
: colorize('brightCyan', ansiChars.checkmark);
|
|
55
|
+
|
|
56
|
+
const passedStr = colorize(
|
|
57
|
+
'brightCyan',
|
|
58
|
+
`${run.summary.passedTasks} passed`,
|
|
59
|
+
);
|
|
60
|
+
const statusStr = hasFailures
|
|
61
|
+
? `${passedStr}, ${colorize('brightRed', `${run.summary.failedTasks} failed`)}`
|
|
62
|
+
: passedStr;
|
|
63
|
+
|
|
64
|
+
// Run ID in bright white and bold, date dimmed, duration in magenta
|
|
65
|
+
lines.push(
|
|
66
|
+
` ${statusIcon} ${colorize('brightWhite', colorize('bold', run.id))} ${colorize('dim', ansiChars.bullet)} ${colorize('gray', dateStr)} ${colorize('dim', ansiChars.bullet)} ${colorize('brightMagenta', durationStr)}`,
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
// Files and tasks info
|
|
70
|
+
lines.push(
|
|
71
|
+
` ${colorize('dim', `${run.summary.totalFiles} files, ${run.summary.totalTasks} tasks:`)} ${statusStr}`,
|
|
72
|
+
);
|
|
73
|
+
lines.push('');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return lines.join('\n');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Format as JSON array
|
|
81
|
+
*/
|
|
82
|
+
formatJson(data: HistoryListResult): string {
|
|
83
|
+
if (data.runs.length === 0) {
|
|
84
|
+
return '[]';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return JSON.stringify(
|
|
88
|
+
data.runs.map((run) => ({
|
|
89
|
+
duration: run.duration,
|
|
90
|
+
failed: run.summary.failedTasks,
|
|
91
|
+
files: run.summary.totalFiles,
|
|
92
|
+
id: run.id,
|
|
93
|
+
passed: run.summary.passedTasks,
|
|
94
|
+
startTime: run.startTime,
|
|
95
|
+
tasks: run.summary.totalTasks,
|
|
96
|
+
})),
|
|
97
|
+
null,
|
|
98
|
+
2,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Show Formatter
|
|
3
|
+
*
|
|
4
|
+
* Formats detailed benchmark run display in human and JSON formats.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { relative } from 'node:path';
|
|
8
|
+
|
|
9
|
+
import type { ShowResult } from '../../services/history/models.js';
|
|
10
|
+
import type { HistoryFormatter } from './base.js';
|
|
11
|
+
|
|
12
|
+
import { ansiChars, colorize } from '../../utils/ansi.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Formatter for history show command
|
|
16
|
+
*/
|
|
17
|
+
export class HistoryShowFormatter implements HistoryFormatter<ShowResult> {
|
|
18
|
+
/**
|
|
19
|
+
* Format as human-readable detailed view
|
|
20
|
+
*/
|
|
21
|
+
formatHuman(data: ShowResult): string {
|
|
22
|
+
const lines: string[] = [];
|
|
23
|
+
|
|
24
|
+
// Header with run ID
|
|
25
|
+
lines.push(
|
|
26
|
+
colorize(
|
|
27
|
+
'cyan',
|
|
28
|
+
colorize(
|
|
29
|
+
'bold',
|
|
30
|
+
`\nBenchmark Run: ${colorize('brightWhite', colorize('bold', data.id))}`,
|
|
31
|
+
),
|
|
32
|
+
),
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
// Run details (indented by 2 spaces)
|
|
36
|
+
lines.push(
|
|
37
|
+
` ${colorize('brightCyan', ansiChars.bullet)} ${colorize('white', data.startTime.toLocaleString())}`,
|
|
38
|
+
);
|
|
39
|
+
lines.push(
|
|
40
|
+
` ${colorize('brightCyan', ansiChars.bullet)} ${colorize('white', 'Duration:')} ${colorize('magenta', `${(data.duration / 1000).toFixed(1)}s`)}`,
|
|
41
|
+
);
|
|
42
|
+
lines.push(
|
|
43
|
+
` ${colorize('brightCyan', ansiChars.bullet)} Node.js ${colorize('brightWhite', data.environment.nodeVersion)} on ${colorize('brightWhite', data.environment.platform)} (${colorize('brightWhite', data.environment.arch)})`,
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
// CPU and system info
|
|
47
|
+
lines.push(
|
|
48
|
+
` ${colorize('brightCyan', ansiChars.bullet)} ${colorize('brightWhite', String(data.environment.cpu.cores))} cores @ ${colorize('brightWhite', `${data.environment.cpu.speed}MHz`)} on ${colorize('brightWhite', data.environment.cpu.model)}`,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
if (data.git) {
|
|
52
|
+
lines.push(
|
|
53
|
+
` ${colorize('brightCyan', ansiChars.bullet)} ${colorize('brightBlue', data.git.branch)}@${colorize('dim', data.git.commit.substring(0, 8))}`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Summary section
|
|
58
|
+
lines.push('');
|
|
59
|
+
lines.push(colorize('cyan', 'Summary'));
|
|
60
|
+
lines.push(
|
|
61
|
+
` ${colorize('dim', ansiChars.smallSquare)} Files: ${colorize('brightWhite', String(data.summary.totalFiles))}`,
|
|
62
|
+
);
|
|
63
|
+
lines.push(
|
|
64
|
+
` ${colorize('dim', ansiChars.smallSquare)} Suites: ${colorize('brightWhite', String(data.summary.totalSuites))}`,
|
|
65
|
+
);
|
|
66
|
+
lines.push(
|
|
67
|
+
` ${colorize('dim', ansiChars.smallSquare)} Tasks: ${colorize('brightWhite', String(data.summary.totalTasks))}`,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
lines.push(
|
|
71
|
+
` ${colorize('dim', ansiChars.smallSquare)} Passed: ${colorize('brightCyan', String(data.summary.passedTasks))}`,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (data.summary.failedTasks > 0) {
|
|
75
|
+
lines.push(
|
|
76
|
+
` ${colorize('dim', ansiChars.smallSquare)} Failed: ${colorize('brightRed', colorize('bold', String(data.summary.failedTasks)))}`,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Detailed results
|
|
81
|
+
lines.push('');
|
|
82
|
+
lines.push(colorize('cyan', 'Results'));
|
|
83
|
+
lines.push('');
|
|
84
|
+
|
|
85
|
+
for (const file of data.files) {
|
|
86
|
+
// Display filepath as relative if within cwd, otherwise absolute
|
|
87
|
+
const displayPath = relative(process.cwd(), file.filePath);
|
|
88
|
+
const finalPath = displayPath.startsWith('..')
|
|
89
|
+
? file.filePath
|
|
90
|
+
: displayPath;
|
|
91
|
+
|
|
92
|
+
lines.push(
|
|
93
|
+
`${colorize('dim', ansiChars.bullet)} ${colorize('brightMagenta', colorize('bold', finalPath))}`,
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
for (const suite of file.suites) {
|
|
97
|
+
lines.push(
|
|
98
|
+
` ${colorize('dim', ansiChars.bullet)} ${colorize('brightWhite', suite.name)}`,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
for (const task of suite.tasks) {
|
|
102
|
+
const statusIcon = task.error
|
|
103
|
+
? colorize('brightRed', ansiChars.cross)
|
|
104
|
+
: colorize('brightCyan', ansiChars.checkmark);
|
|
105
|
+
|
|
106
|
+
if (task.error) {
|
|
107
|
+
lines.push(
|
|
108
|
+
` ${statusIcon} ${colorize('white', task.name)} ${colorize('dim', ansiChars.bullet)} ${colorize('brightRed', 'failed')}`,
|
|
109
|
+
);
|
|
110
|
+
} else {
|
|
111
|
+
const mean = formatTime(task.mean);
|
|
112
|
+
const opsStr = task.opsPerSecond.toLocaleString('en-US', {
|
|
113
|
+
maximumFractionDigits: 0,
|
|
114
|
+
});
|
|
115
|
+
const rmeStr = task.marginOfError.toFixed(2);
|
|
116
|
+
|
|
117
|
+
lines.push(
|
|
118
|
+
` ${statusIcon} ${colorize('white', task.name)}: ${colorize('brightMagenta', mean)} ${colorize('dim', ansiChars.bullet)} ${colorize('brightBlue', `${ansiChars.plusMinus}${rmeStr}`)} ${colorize('dim', ansiChars.bullet)} ${colorize('magenta', opsStr)} ops/sec`,
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
if (task.iterations > 0) {
|
|
122
|
+
lines.push(
|
|
123
|
+
` ${colorize('dim', `${task.iterations} iterations, cv: ${task.cv.toFixed(1)}%`)}`,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
lines.push('');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return lines.join('\n');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Format as complete JSON
|
|
138
|
+
*/
|
|
139
|
+
formatJson(data: ShowResult): string {
|
|
140
|
+
return JSON.stringify(data, null, 2);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Format nanoseconds as a human-readable time string
|
|
146
|
+
*/
|
|
147
|
+
const formatTime = (ns: number): string => {
|
|
148
|
+
if (ns < 1000) {
|
|
149
|
+
return `${ns.toFixed(2)}ns`;
|
|
150
|
+
}
|
|
151
|
+
if (ns < 1000000) {
|
|
152
|
+
return `${(ns / 1000).toFixed(3)}µs`;
|
|
153
|
+
}
|
|
154
|
+
return `${(ns / 1000000).toFixed(3)}ms`;
|
|
155
|
+
};
|