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,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Trends Formatter
|
|
4
|
+
*
|
|
5
|
+
* Formats performance trend analysis with visualizations in human and JSON
|
|
6
|
+
* formats.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.HistoryTrendsFormatter = void 0;
|
|
10
|
+
const node_util_1 = require("node:util");
|
|
11
|
+
const ansi_js_1 = require("../../utils/ansi.cjs");
|
|
12
|
+
const visualization_js_1 = require("./visualization.cjs");
|
|
13
|
+
/**
|
|
14
|
+
* Nanoseconds per millisecond conversion constant
|
|
15
|
+
*/
|
|
16
|
+
const NS_PER_MS = 1_000_000;
|
|
17
|
+
/**
|
|
18
|
+
* Nanoseconds per microsecond conversion constant
|
|
19
|
+
*/
|
|
20
|
+
const NS_PER_US = 1_000;
|
|
21
|
+
/**
|
|
22
|
+
* Intelligently format a time range with appropriate precision Displays
|
|
23
|
+
* microseconds for small values (< 1ms) for better clarity
|
|
24
|
+
*/
|
|
25
|
+
const formatTimeRange = (minNs, maxNs) => {
|
|
26
|
+
// If both values are below 1ms, show in microseconds for better precision
|
|
27
|
+
if (maxNs < NS_PER_MS) {
|
|
28
|
+
const minUs = minNs / NS_PER_US;
|
|
29
|
+
const maxUs = maxNs / NS_PER_US;
|
|
30
|
+
return `${minUs.toFixed(2)}-${maxUs.toFixed(2)}µs`;
|
|
31
|
+
}
|
|
32
|
+
// Otherwise show in milliseconds
|
|
33
|
+
const minMs = minNs / NS_PER_MS;
|
|
34
|
+
const maxMs = maxNs / NS_PER_MS;
|
|
35
|
+
return `${minMs.toFixed(3)}-${maxMs.toFixed(3)}ms`;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Calculate visible string length, stripping ANSI escape codes
|
|
39
|
+
*/
|
|
40
|
+
const getVisualLength = (str) => (0, node_util_1.stripVTControlCharacters)(str).length;
|
|
41
|
+
/**
|
|
42
|
+
* Formatter for history trends command
|
|
43
|
+
*/
|
|
44
|
+
class HistoryTrendsFormatter {
|
|
45
|
+
/**
|
|
46
|
+
* Format as human-readable trends with visualizations
|
|
47
|
+
*/
|
|
48
|
+
formatHuman(data) {
|
|
49
|
+
const lines = [];
|
|
50
|
+
lines.push((0, ansi_js_1.colorize)('brightMagenta', (0, ansi_js_1.colorize)('bold', `\nPerformance Trends (${data.runs} runs)`)));
|
|
51
|
+
if (data.timespan.start && data.timespan.end) {
|
|
52
|
+
lines.push((0, ansi_js_1.colorize)('dim', `Time range: ${data.timespan.start.toLocaleDateString()} to ${data.timespan.end.toLocaleDateString()}`));
|
|
53
|
+
}
|
|
54
|
+
lines.push('');
|
|
55
|
+
// Summary statistics
|
|
56
|
+
lines.push((0, ansi_js_1.colorize)('brightBlue', 'Summary:'));
|
|
57
|
+
lines.push(` ${(0, ansi_js_1.colorize)('brightCyan', '▲')} ${data.summary.improvingTasks} improving ${(0, ansi_js_1.colorize)('brightRed', '▼')} ${data.summary.degradingTasks} degrading ${(0, ansi_js_1.colorize)('dim', '→')} ${data.summary.stableTasks} stable`);
|
|
58
|
+
lines.push('');
|
|
59
|
+
// Task Performance Summary Table
|
|
60
|
+
lines.push((0, ansi_js_1.colorize)('brightMagenta', 'Task Performance Summary:'));
|
|
61
|
+
lines.push('');
|
|
62
|
+
for (const trendData of data.trends) {
|
|
63
|
+
// Show top 20
|
|
64
|
+
const trendIcon = trendData.trend === 'improving'
|
|
65
|
+
? (0, ansi_js_1.colorize)('brightCyan', '▲')
|
|
66
|
+
: trendData.trend === 'degrading'
|
|
67
|
+
? (0, ansi_js_1.colorize)('brightRed', '▼')
|
|
68
|
+
: (0, ansi_js_1.colorize)('dim', '→');
|
|
69
|
+
const changeColor = trendData.percentChange < -5
|
|
70
|
+
? 'brightCyan'
|
|
71
|
+
: trendData.percentChange > 5
|
|
72
|
+
? 'brightRed'
|
|
73
|
+
: 'dim';
|
|
74
|
+
const changeSign = trendData.percentChange >= 0 ? '+' : '';
|
|
75
|
+
const changeStr = `${changeSign}${trendData.percentChange.toFixed(1)}%`;
|
|
76
|
+
// Generate sparkline - scale with number of data points (min 12, max 20)
|
|
77
|
+
const values = trendData.dataPoints.map((dp) => dp.mean);
|
|
78
|
+
const sparklineWidth = Math.min(20, Math.max(12, trendData.runs));
|
|
79
|
+
const sparkline = (0, visualization_js_1.generateSparkline)(values, sparklineWidth);
|
|
80
|
+
const sparklineColor = trendData.trend === 'improving'
|
|
81
|
+
? 'brightCyan'
|
|
82
|
+
: trendData.trend === 'degrading'
|
|
83
|
+
? 'brightRed'
|
|
84
|
+
: 'cyan';
|
|
85
|
+
const taskName = (0, ansi_js_1.colorize)('white', trendData.task);
|
|
86
|
+
const percentDisplay = (0, ansi_js_1.colorize)(changeColor, changeStr.padStart(8));
|
|
87
|
+
const sparklineDisplay = (0, ansi_js_1.colorize)(sparklineColor, sparkline);
|
|
88
|
+
// Layout: icon (2) + task name + padding + percent (8) + spaces (2) + sparkline
|
|
89
|
+
// Position percent+graph at visual column 60 for consistent alignment
|
|
90
|
+
const prefix = ` ${trendIcon} ${taskName}`;
|
|
91
|
+
const prefixVisualLength = getVisualLength(prefix);
|
|
92
|
+
const targetColumn = 60;
|
|
93
|
+
if (prefixVisualLength > targetColumn) {
|
|
94
|
+
// Task name is too long, wrap to next line
|
|
95
|
+
lines.push(prefix);
|
|
96
|
+
lines.push(`${' '.repeat(targetColumn)}${percentDisplay} ${sparklineDisplay}`);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// Fit on one line with padding
|
|
100
|
+
const padding = Math.max(1, targetColumn - prefixVisualLength);
|
|
101
|
+
const paddingStr = ' '.repeat(padding);
|
|
102
|
+
lines.push(`${prefix}${paddingStr}${percentDisplay} ${sparklineDisplay}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Show all trends (no limit)
|
|
106
|
+
lines.push('');
|
|
107
|
+
// Show regressions if any
|
|
108
|
+
if (data.regressions.length > 0) {
|
|
109
|
+
lines.push((0, ansi_js_1.colorize)('brightRed', (0, ansi_js_1.colorize)('bold', 'Regressions Detected:')));
|
|
110
|
+
lines.push('');
|
|
111
|
+
for (const regression of data.regressions) {
|
|
112
|
+
lines.push(` ${(0, ansi_js_1.colorize)('brightRed', '▼')} ${(0, ansi_js_1.colorize)('white', regression.task)}: ${(0, ansi_js_1.colorize)('brightRed', `${regression.percentChange.toFixed(1)}% slower`)} (${regression.runs} runs)`);
|
|
113
|
+
}
|
|
114
|
+
lines.push('');
|
|
115
|
+
}
|
|
116
|
+
// Show low-confidence regressions (insufficient data)
|
|
117
|
+
if (data.lowConfidenceRegressions.length > 0) {
|
|
118
|
+
lines.push((0, ansi_js_1.colorize)('brightYellow', (0, ansi_js_1.colorize)('bold', '! Potential Regressions (insufficient data):')));
|
|
119
|
+
lines.push('');
|
|
120
|
+
for (const regression of data.lowConfidenceRegressions) {
|
|
121
|
+
lines.push(` ${(0, ansi_js_1.colorize)('brightYellow', '!')} ${(0, ansi_js_1.colorize)('white', regression.task)}: ${(0, ansi_js_1.colorize)('brightYellow', `${regression.percentChange.toFixed(1)}% slower`)} (${regression.runs} run${regression.runs !== 1 ? 's' : ''})`);
|
|
122
|
+
}
|
|
123
|
+
lines.push('');
|
|
124
|
+
}
|
|
125
|
+
// Show performance distribution for most important task (highest RME) if we have enough data
|
|
126
|
+
// Find task with highest relative margin of error - the most variable/unreliable one
|
|
127
|
+
const mostImportantTrend = data.trends
|
|
128
|
+
.filter((t) => t.runs >= 5)
|
|
129
|
+
.sort((a, b) => {
|
|
130
|
+
const rmeA = (a.statistics.stdDeviation / a.statistics.mean) * 100;
|
|
131
|
+
const rmeB = (b.statistics.stdDeviation / b.statistics.mean) * 100;
|
|
132
|
+
return rmeB - rmeA; // Descending order (highest RME first)
|
|
133
|
+
})[0];
|
|
134
|
+
if (mostImportantTrend) {
|
|
135
|
+
lines.push((0, ansi_js_1.colorize)('brightMagenta', 'Performance Distribution (most variable task):'));
|
|
136
|
+
lines.push((0, ansi_js_1.colorize)('white', mostImportantTrend.task));
|
|
137
|
+
const cv = ((mostImportantTrend.statistics.stdDeviation /
|
|
138
|
+
mostImportantTrend.statistics.mean) *
|
|
139
|
+
100).toFixed(1);
|
|
140
|
+
lines.push((0, ansi_js_1.colorize)('dim', ` Variability: ${cv}%`));
|
|
141
|
+
lines.push('');
|
|
142
|
+
// Create distribution buckets
|
|
143
|
+
const values = mostImportantTrend.dataPoints.map((dp) => dp.mean);
|
|
144
|
+
const min = Math.min(...values);
|
|
145
|
+
const max = Math.max(...values);
|
|
146
|
+
const range = max - min;
|
|
147
|
+
const numBuckets = Math.min(5, mostImportantTrend.runs);
|
|
148
|
+
const bucketSize = range / numBuckets;
|
|
149
|
+
const buckets = [];
|
|
150
|
+
for (let i = 0; i < numBuckets; i++) {
|
|
151
|
+
const bucketMin = min + i * bucketSize;
|
|
152
|
+
const bucketMax = min + (i + 1) * bucketSize;
|
|
153
|
+
const count = values.filter((v) => v >= bucketMin &&
|
|
154
|
+
(i === numBuckets - 1 ? v <= bucketMax : v < bucketMax)).length;
|
|
155
|
+
const label = formatTimeRange(bucketMin, bucketMax);
|
|
156
|
+
buckets.push({
|
|
157
|
+
count,
|
|
158
|
+
label,
|
|
159
|
+
max: bucketMax,
|
|
160
|
+
min: bucketMin,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
// Filter out empty buckets for cleaner display
|
|
164
|
+
const nonEmptyBuckets = buckets.filter((b) => b.count > 0);
|
|
165
|
+
const chart = (0, visualization_js_1.generateBarChart)(nonEmptyBuckets, 25);
|
|
166
|
+
for (const line of chart) {
|
|
167
|
+
lines.push((0, ansi_js_1.colorize)('brightCyan', line));
|
|
168
|
+
}
|
|
169
|
+
lines.push('');
|
|
170
|
+
lines.push((0, ansi_js_1.colorize)('dim', ` Mean: ${(mostImportantTrend.statistics.mean / NS_PER_MS).toFixed(3)}ms Median: ${(mostImportantTrend.statistics.median / NS_PER_MS).toFixed(3)}ms StdDev: ${(mostImportantTrend.statistics.stdDeviation / NS_PER_MS).toFixed(3)}ms`));
|
|
171
|
+
lines.push('');
|
|
172
|
+
}
|
|
173
|
+
return lines.join('\n');
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Format as JSON
|
|
177
|
+
*/
|
|
178
|
+
formatJson(data) {
|
|
179
|
+
return JSON.stringify({
|
|
180
|
+
regressions: data.regressions,
|
|
181
|
+
summary: {
|
|
182
|
+
degradingTasks: data.summary.degradingTasks,
|
|
183
|
+
improvingTasks: data.summary.improvingTasks,
|
|
184
|
+
runs: data.runs,
|
|
185
|
+
stableTasks: data.summary.stableTasks,
|
|
186
|
+
timespan: data.timespan,
|
|
187
|
+
totalTasks: data.summary.totalTasks,
|
|
188
|
+
},
|
|
189
|
+
trends: data.trends,
|
|
190
|
+
}, null, 2);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
exports.HistoryTrendsFormatter = HistoryTrendsFormatter;
|
|
194
|
+
//# sourceMappingURL=trends.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trends.js","sourceRoot":"","sources":["../../../src/formatters/history/trends.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trends Formatter
|
|
3
|
+
*
|
|
4
|
+
* Formats performance trend analysis with visualizations in human and JSON
|
|
5
|
+
* formats.
|
|
6
|
+
*/
|
|
7
|
+
import type { TrendsResult } from "../../services/history/models.cjs";
|
|
8
|
+
import type { HistoryFormatter } from "./base.cjs";
|
|
9
|
+
/**
|
|
10
|
+
* Formatter for history trends command
|
|
11
|
+
*/
|
|
12
|
+
export declare class HistoryTrendsFormatter implements HistoryFormatter<TrendsResult> {
|
|
13
|
+
/**
|
|
14
|
+
* Format as human-readable trends with visualizations
|
|
15
|
+
*/
|
|
16
|
+
formatHuman(data: TrendsResult): string;
|
|
17
|
+
/**
|
|
18
|
+
* Format as JSON
|
|
19
|
+
*/
|
|
20
|
+
formatJson(data: TrendsResult): string;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=trends.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trends.d.ts","sourceRoot":"","sources":["../../../src/formatters/history/trends.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAEV,YAAY,EACb,0CAAyC;AAC1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAkB;AAuClD;;GAEG;AACH,qBAAa,sBAAuB,YAAW,gBAAgB,CAAC,YAAY,CAAC;IAC3E;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM;IAwMvC;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM;CAkBvC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trends Formatter
|
|
3
|
+
*
|
|
4
|
+
* Formats performance trend analysis with visualizations in human and JSON
|
|
5
|
+
* formats.
|
|
6
|
+
*/
|
|
7
|
+
import type { TrendsResult } from "../../services/history/models.js";
|
|
8
|
+
import type { HistoryFormatter } from "./base.js";
|
|
9
|
+
/**
|
|
10
|
+
* Formatter for history trends command
|
|
11
|
+
*/
|
|
12
|
+
export declare class HistoryTrendsFormatter implements HistoryFormatter<TrendsResult> {
|
|
13
|
+
/**
|
|
14
|
+
* Format as human-readable trends with visualizations
|
|
15
|
+
*/
|
|
16
|
+
formatHuman(data: TrendsResult): string;
|
|
17
|
+
/**
|
|
18
|
+
* Format as JSON
|
|
19
|
+
*/
|
|
20
|
+
formatJson(data: TrendsResult): string;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=trends.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trends.d.ts","sourceRoot":"","sources":["../../../src/formatters/history/trends.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAEV,YAAY,EACb,yCAAyC;AAC1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB;AAuClD;;GAEG;AACH,qBAAa,sBAAuB,YAAW,gBAAgB,CAAC,YAAY,CAAC;IAC3E;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM;IAwMvC;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM;CAkBvC"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trends Formatter
|
|
3
|
+
*
|
|
4
|
+
* Formats performance trend analysis with visualizations in human and JSON
|
|
5
|
+
* formats.
|
|
6
|
+
*/
|
|
7
|
+
import { stripVTControlCharacters } from 'node:util';
|
|
8
|
+
import { colorize } from "../../utils/ansi.js";
|
|
9
|
+
import { generateBarChart, generateSparkline } from "./visualization.js";
|
|
10
|
+
/**
|
|
11
|
+
* Nanoseconds per millisecond conversion constant
|
|
12
|
+
*/
|
|
13
|
+
const NS_PER_MS = 1_000_000;
|
|
14
|
+
/**
|
|
15
|
+
* Nanoseconds per microsecond conversion constant
|
|
16
|
+
*/
|
|
17
|
+
const NS_PER_US = 1_000;
|
|
18
|
+
/**
|
|
19
|
+
* Intelligently format a time range with appropriate precision Displays
|
|
20
|
+
* microseconds for small values (< 1ms) for better clarity
|
|
21
|
+
*/
|
|
22
|
+
const formatTimeRange = (minNs, maxNs) => {
|
|
23
|
+
// If both values are below 1ms, show in microseconds for better precision
|
|
24
|
+
if (maxNs < NS_PER_MS) {
|
|
25
|
+
const minUs = minNs / NS_PER_US;
|
|
26
|
+
const maxUs = maxNs / NS_PER_US;
|
|
27
|
+
return `${minUs.toFixed(2)}-${maxUs.toFixed(2)}µs`;
|
|
28
|
+
}
|
|
29
|
+
// Otherwise show in milliseconds
|
|
30
|
+
const minMs = minNs / NS_PER_MS;
|
|
31
|
+
const maxMs = maxNs / NS_PER_MS;
|
|
32
|
+
return `${minMs.toFixed(3)}-${maxMs.toFixed(3)}ms`;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Calculate visible string length, stripping ANSI escape codes
|
|
36
|
+
*/
|
|
37
|
+
const getVisualLength = (str) => stripVTControlCharacters(str).length;
|
|
38
|
+
/**
|
|
39
|
+
* Formatter for history trends command
|
|
40
|
+
*/
|
|
41
|
+
export class HistoryTrendsFormatter {
|
|
42
|
+
/**
|
|
43
|
+
* Format as human-readable trends with visualizations
|
|
44
|
+
*/
|
|
45
|
+
formatHuman(data) {
|
|
46
|
+
const lines = [];
|
|
47
|
+
lines.push(colorize('brightMagenta', colorize('bold', `\nPerformance Trends (${data.runs} runs)`)));
|
|
48
|
+
if (data.timespan.start && data.timespan.end) {
|
|
49
|
+
lines.push(colorize('dim', `Time range: ${data.timespan.start.toLocaleDateString()} to ${data.timespan.end.toLocaleDateString()}`));
|
|
50
|
+
}
|
|
51
|
+
lines.push('');
|
|
52
|
+
// Summary statistics
|
|
53
|
+
lines.push(colorize('brightBlue', 'Summary:'));
|
|
54
|
+
lines.push(` ${colorize('brightCyan', '▲')} ${data.summary.improvingTasks} improving ${colorize('brightRed', '▼')} ${data.summary.degradingTasks} degrading ${colorize('dim', '→')} ${data.summary.stableTasks} stable`);
|
|
55
|
+
lines.push('');
|
|
56
|
+
// Task Performance Summary Table
|
|
57
|
+
lines.push(colorize('brightMagenta', 'Task Performance Summary:'));
|
|
58
|
+
lines.push('');
|
|
59
|
+
for (const trendData of data.trends) {
|
|
60
|
+
// Show top 20
|
|
61
|
+
const trendIcon = trendData.trend === 'improving'
|
|
62
|
+
? colorize('brightCyan', '▲')
|
|
63
|
+
: trendData.trend === 'degrading'
|
|
64
|
+
? colorize('brightRed', '▼')
|
|
65
|
+
: colorize('dim', '→');
|
|
66
|
+
const changeColor = trendData.percentChange < -5
|
|
67
|
+
? 'brightCyan'
|
|
68
|
+
: trendData.percentChange > 5
|
|
69
|
+
? 'brightRed'
|
|
70
|
+
: 'dim';
|
|
71
|
+
const changeSign = trendData.percentChange >= 0 ? '+' : '';
|
|
72
|
+
const changeStr = `${changeSign}${trendData.percentChange.toFixed(1)}%`;
|
|
73
|
+
// Generate sparkline - scale with number of data points (min 12, max 20)
|
|
74
|
+
const values = trendData.dataPoints.map((dp) => dp.mean);
|
|
75
|
+
const sparklineWidth = Math.min(20, Math.max(12, trendData.runs));
|
|
76
|
+
const sparkline = generateSparkline(values, sparklineWidth);
|
|
77
|
+
const sparklineColor = trendData.trend === 'improving'
|
|
78
|
+
? 'brightCyan'
|
|
79
|
+
: trendData.trend === 'degrading'
|
|
80
|
+
? 'brightRed'
|
|
81
|
+
: 'cyan';
|
|
82
|
+
const taskName = colorize('white', trendData.task);
|
|
83
|
+
const percentDisplay = colorize(changeColor, changeStr.padStart(8));
|
|
84
|
+
const sparklineDisplay = colorize(sparklineColor, sparkline);
|
|
85
|
+
// Layout: icon (2) + task name + padding + percent (8) + spaces (2) + sparkline
|
|
86
|
+
// Position percent+graph at visual column 60 for consistent alignment
|
|
87
|
+
const prefix = ` ${trendIcon} ${taskName}`;
|
|
88
|
+
const prefixVisualLength = getVisualLength(prefix);
|
|
89
|
+
const targetColumn = 60;
|
|
90
|
+
if (prefixVisualLength > targetColumn) {
|
|
91
|
+
// Task name is too long, wrap to next line
|
|
92
|
+
lines.push(prefix);
|
|
93
|
+
lines.push(`${' '.repeat(targetColumn)}${percentDisplay} ${sparklineDisplay}`);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// Fit on one line with padding
|
|
97
|
+
const padding = Math.max(1, targetColumn - prefixVisualLength);
|
|
98
|
+
const paddingStr = ' '.repeat(padding);
|
|
99
|
+
lines.push(`${prefix}${paddingStr}${percentDisplay} ${sparklineDisplay}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Show all trends (no limit)
|
|
103
|
+
lines.push('');
|
|
104
|
+
// Show regressions if any
|
|
105
|
+
if (data.regressions.length > 0) {
|
|
106
|
+
lines.push(colorize('brightRed', colorize('bold', 'Regressions Detected:')));
|
|
107
|
+
lines.push('');
|
|
108
|
+
for (const regression of data.regressions) {
|
|
109
|
+
lines.push(` ${colorize('brightRed', '▼')} ${colorize('white', regression.task)}: ${colorize('brightRed', `${regression.percentChange.toFixed(1)}% slower`)} (${regression.runs} runs)`);
|
|
110
|
+
}
|
|
111
|
+
lines.push('');
|
|
112
|
+
}
|
|
113
|
+
// Show low-confidence regressions (insufficient data)
|
|
114
|
+
if (data.lowConfidenceRegressions.length > 0) {
|
|
115
|
+
lines.push(colorize('brightYellow', colorize('bold', '! Potential Regressions (insufficient data):')));
|
|
116
|
+
lines.push('');
|
|
117
|
+
for (const regression of data.lowConfidenceRegressions) {
|
|
118
|
+
lines.push(` ${colorize('brightYellow', '!')} ${colorize('white', regression.task)}: ${colorize('brightYellow', `${regression.percentChange.toFixed(1)}% slower`)} (${regression.runs} run${regression.runs !== 1 ? 's' : ''})`);
|
|
119
|
+
}
|
|
120
|
+
lines.push('');
|
|
121
|
+
}
|
|
122
|
+
// Show performance distribution for most important task (highest RME) if we have enough data
|
|
123
|
+
// Find task with highest relative margin of error - the most variable/unreliable one
|
|
124
|
+
const mostImportantTrend = data.trends
|
|
125
|
+
.filter((t) => t.runs >= 5)
|
|
126
|
+
.sort((a, b) => {
|
|
127
|
+
const rmeA = (a.statistics.stdDeviation / a.statistics.mean) * 100;
|
|
128
|
+
const rmeB = (b.statistics.stdDeviation / b.statistics.mean) * 100;
|
|
129
|
+
return rmeB - rmeA; // Descending order (highest RME first)
|
|
130
|
+
})[0];
|
|
131
|
+
if (mostImportantTrend) {
|
|
132
|
+
lines.push(colorize('brightMagenta', 'Performance Distribution (most variable task):'));
|
|
133
|
+
lines.push(colorize('white', mostImportantTrend.task));
|
|
134
|
+
const cv = ((mostImportantTrend.statistics.stdDeviation /
|
|
135
|
+
mostImportantTrend.statistics.mean) *
|
|
136
|
+
100).toFixed(1);
|
|
137
|
+
lines.push(colorize('dim', ` Variability: ${cv}%`));
|
|
138
|
+
lines.push('');
|
|
139
|
+
// Create distribution buckets
|
|
140
|
+
const values = mostImportantTrend.dataPoints.map((dp) => dp.mean);
|
|
141
|
+
const min = Math.min(...values);
|
|
142
|
+
const max = Math.max(...values);
|
|
143
|
+
const range = max - min;
|
|
144
|
+
const numBuckets = Math.min(5, mostImportantTrend.runs);
|
|
145
|
+
const bucketSize = range / numBuckets;
|
|
146
|
+
const buckets = [];
|
|
147
|
+
for (let i = 0; i < numBuckets; i++) {
|
|
148
|
+
const bucketMin = min + i * bucketSize;
|
|
149
|
+
const bucketMax = min + (i + 1) * bucketSize;
|
|
150
|
+
const count = values.filter((v) => v >= bucketMin &&
|
|
151
|
+
(i === numBuckets - 1 ? v <= bucketMax : v < bucketMax)).length;
|
|
152
|
+
const label = formatTimeRange(bucketMin, bucketMax);
|
|
153
|
+
buckets.push({
|
|
154
|
+
count,
|
|
155
|
+
label,
|
|
156
|
+
max: bucketMax,
|
|
157
|
+
min: bucketMin,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
// Filter out empty buckets for cleaner display
|
|
161
|
+
const nonEmptyBuckets = buckets.filter((b) => b.count > 0);
|
|
162
|
+
const chart = generateBarChart(nonEmptyBuckets, 25);
|
|
163
|
+
for (const line of chart) {
|
|
164
|
+
lines.push(colorize('brightCyan', line));
|
|
165
|
+
}
|
|
166
|
+
lines.push('');
|
|
167
|
+
lines.push(colorize('dim', ` Mean: ${(mostImportantTrend.statistics.mean / NS_PER_MS).toFixed(3)}ms Median: ${(mostImportantTrend.statistics.median / NS_PER_MS).toFixed(3)}ms StdDev: ${(mostImportantTrend.statistics.stdDeviation / NS_PER_MS).toFixed(3)}ms`));
|
|
168
|
+
lines.push('');
|
|
169
|
+
}
|
|
170
|
+
return lines.join('\n');
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Format as JSON
|
|
174
|
+
*/
|
|
175
|
+
formatJson(data) {
|
|
176
|
+
return JSON.stringify({
|
|
177
|
+
regressions: data.regressions,
|
|
178
|
+
summary: {
|
|
179
|
+
degradingTasks: data.summary.degradingTasks,
|
|
180
|
+
improvingTasks: data.summary.improvingTasks,
|
|
181
|
+
runs: data.runs,
|
|
182
|
+
stableTasks: data.summary.stableTasks,
|
|
183
|
+
timespan: data.timespan,
|
|
184
|
+
totalTasks: data.summary.totalTasks,
|
|
185
|
+
},
|
|
186
|
+
trends: data.trends,
|
|
187
|
+
}, null, 2);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=trends.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trends.js","sourceRoot":"","sources":["../../../src/formatters/history/trends.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Visualization Utilities for History Formatters
|
|
4
|
+
*
|
|
5
|
+
* Pure functions for generating ASCII visualizations (sparklines, bar charts)
|
|
6
|
+
* for trend analysis and performance distribution displays.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.generateSparkline = exports.generateBarChart = void 0;
|
|
10
|
+
/**
|
|
11
|
+
* Generate bar chart histogram from distribution buckets
|
|
12
|
+
*
|
|
13
|
+
* @param distribution - Array of distribution buckets with counts
|
|
14
|
+
* @param maxWidth - Maximum width of bars (default 20)
|
|
15
|
+
* @returns Array of formatted bar chart lines
|
|
16
|
+
*/
|
|
17
|
+
const generateBarChart = (distribution, maxWidth = 20) => {
|
|
18
|
+
if (distribution.length === 0) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
// Find maximum count for scaling
|
|
22
|
+
const maxCount = Math.max(...distribution.map((b) => b.count));
|
|
23
|
+
if (maxCount === 0) {
|
|
24
|
+
return distribution.map((bucket) => ` ${bucket.label} (0 runs)`);
|
|
25
|
+
}
|
|
26
|
+
// Block characters for bar visualization
|
|
27
|
+
const fullBlock = '█';
|
|
28
|
+
const lightBlock = '░';
|
|
29
|
+
return distribution.map((bucket) => {
|
|
30
|
+
const ratio = bucket.count / maxCount;
|
|
31
|
+
const barLength = Math.round(ratio * maxWidth);
|
|
32
|
+
const fullBlocks = fullBlock.repeat(barLength);
|
|
33
|
+
const emptyBlocks = lightBlock.repeat(maxWidth - barLength);
|
|
34
|
+
return ` ${fullBlocks}${emptyBlocks} ${bucket.label} (${bucket.count} run${bucket.count !== 1 ? 's' : ''})`;
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
exports.generateBarChart = generateBarChart;
|
|
38
|
+
/**
|
|
39
|
+
* Generate ASCII sparkline from values
|
|
40
|
+
*
|
|
41
|
+
* @param values - Array of numeric values to visualize
|
|
42
|
+
* @param width - Maximum width of sparkline (downsamples if needed)
|
|
43
|
+
* @returns ASCII sparkline string using block characters
|
|
44
|
+
*/
|
|
45
|
+
const generateSparkline = (values, width) => {
|
|
46
|
+
if (values.length === 0) {
|
|
47
|
+
return '';
|
|
48
|
+
}
|
|
49
|
+
// Sparkline characters from lowest to highest
|
|
50
|
+
const sparkChars = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
|
|
51
|
+
// Downsample if width is specified and values exceed it
|
|
52
|
+
let processedValues = values;
|
|
53
|
+
if (width && values.length > width) {
|
|
54
|
+
const step = values.length / width;
|
|
55
|
+
processedValues = [];
|
|
56
|
+
for (let i = 0; i < width; i++) {
|
|
57
|
+
const idx = Math.floor(i * step);
|
|
58
|
+
processedValues.push(values[idx] ?? 0);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Find min and max for scaling
|
|
62
|
+
const min = Math.min(...processedValues);
|
|
63
|
+
const max = Math.max(...processedValues);
|
|
64
|
+
const range = max - min;
|
|
65
|
+
// Handle case where all values are the same
|
|
66
|
+
if (range === 0) {
|
|
67
|
+
return (sparkChars[4] ?? '▄').repeat(processedValues.length); // Use middle character
|
|
68
|
+
}
|
|
69
|
+
// Map each value to a sparkline character
|
|
70
|
+
return processedValues
|
|
71
|
+
.map((value) => {
|
|
72
|
+
const normalized = (value - min) / range;
|
|
73
|
+
const index = Math.min(Math.floor(normalized * sparkChars.length), sparkChars.length - 1);
|
|
74
|
+
return sparkChars[index] ?? '▄';
|
|
75
|
+
})
|
|
76
|
+
.join('');
|
|
77
|
+
};
|
|
78
|
+
exports.generateSparkline = generateSparkline;
|
|
79
|
+
//# sourceMappingURL=visualization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visualization.js","sourceRoot":"","sources":["../../../src/formatters/history/visualization.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visualization Utilities for History Formatters
|
|
3
|
+
*
|
|
4
|
+
* Pure functions for generating ASCII visualizations (sparklines, bar charts)
|
|
5
|
+
* for trend analysis and performance distribution displays.
|
|
6
|
+
*/
|
|
7
|
+
import type { DistributionBucket } from "../../services/history/models.cjs";
|
|
8
|
+
/**
|
|
9
|
+
* Generate bar chart histogram from distribution buckets
|
|
10
|
+
*
|
|
11
|
+
* @param distribution - Array of distribution buckets with counts
|
|
12
|
+
* @param maxWidth - Maximum width of bars (default 20)
|
|
13
|
+
* @returns Array of formatted bar chart lines
|
|
14
|
+
*/
|
|
15
|
+
export declare const generateBarChart: (distribution: DistributionBucket[], maxWidth?: number) => string[];
|
|
16
|
+
/**
|
|
17
|
+
* Generate ASCII sparkline from values
|
|
18
|
+
*
|
|
19
|
+
* @param values - Array of numeric values to visualize
|
|
20
|
+
* @param width - Maximum width of sparkline (downsamples if needed)
|
|
21
|
+
* @returns ASCII sparkline string using block characters
|
|
22
|
+
*/
|
|
23
|
+
export declare const generateSparkline: (values: number[], width?: number) => string;
|
|
24
|
+
//# sourceMappingURL=visualization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visualization.d.ts","sourceRoot":"","sources":["../../../src/formatters/history/visualization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,0CAAyC;AAE3E;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAC3B,cAAc,kBAAkB,EAAE,EAClC,iBAAa,KACZ,MAAM,EAwBR,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,EAAE,EAAE,QAAQ,MAAM,KAAG,MAwCpE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visualization Utilities for History Formatters
|
|
3
|
+
*
|
|
4
|
+
* Pure functions for generating ASCII visualizations (sparklines, bar charts)
|
|
5
|
+
* for trend analysis and performance distribution displays.
|
|
6
|
+
*/
|
|
7
|
+
import type { DistributionBucket } from "../../services/history/models.js";
|
|
8
|
+
/**
|
|
9
|
+
* Generate bar chart histogram from distribution buckets
|
|
10
|
+
*
|
|
11
|
+
* @param distribution - Array of distribution buckets with counts
|
|
12
|
+
* @param maxWidth - Maximum width of bars (default 20)
|
|
13
|
+
* @returns Array of formatted bar chart lines
|
|
14
|
+
*/
|
|
15
|
+
export declare const generateBarChart: (distribution: DistributionBucket[], maxWidth?: number) => string[];
|
|
16
|
+
/**
|
|
17
|
+
* Generate ASCII sparkline from values
|
|
18
|
+
*
|
|
19
|
+
* @param values - Array of numeric values to visualize
|
|
20
|
+
* @param width - Maximum width of sparkline (downsamples if needed)
|
|
21
|
+
* @returns ASCII sparkline string using block characters
|
|
22
|
+
*/
|
|
23
|
+
export declare const generateSparkline: (values: number[], width?: number) => string;
|
|
24
|
+
//# sourceMappingURL=visualization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visualization.d.ts","sourceRoot":"","sources":["../../../src/formatters/history/visualization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,yCAAyC;AAE3E;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAC3B,cAAc,kBAAkB,EAAE,EAClC,iBAAa,KACZ,MAAM,EAwBR,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,EAAE,EAAE,QAAQ,MAAM,KAAG,MAwCpE,CAAC"}
|