modestbench 0.1.0 → 0.3.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 +31 -0
- package/README.md +162 -57
- package/dist/bootstrap.cjs +10 -10
- 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 -5
- package/dist/bootstrap.js.map +1 -1
- package/dist/cli/commands/analyze.cjs +60 -0
- package/dist/cli/commands/analyze.cjs.map +1 -0
- package/dist/cli/commands/analyze.d.cts +35 -0
- package/dist/cli/commands/analyze.d.cts.map +1 -0
- package/dist/cli/commands/analyze.d.ts +35 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +56 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/baseline.cjs +404 -0
- package/dist/cli/commands/baseline.cjs.map +1 -0
- package/dist/cli/commands/baseline.d.cts +72 -0
- package/dist/cli/commands/baseline.d.cts.map +1 -0
- package/dist/cli/commands/baseline.d.ts +72 -0
- package/dist/cli/commands/baseline.d.ts.map +1 -0
- package/dist/cli/commands/baseline.js +396 -0
- package/dist/cli/commands/baseline.js.map +1 -0
- package/dist/cli/commands/history.cjs +108 -266
- 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 -268
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/init.cjs +88 -155
- package/dist/cli/commands/init.cjs.map +1 -1
- package/dist/cli/commands/init.d.cts +4 -4
- package/dist/cli/commands/init.d.cts.map +1 -1
- package/dist/cli/commands/init.d.ts +4 -4
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +88 -155
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/run.cjs +143 -112
- package/dist/cli/commands/run.cjs.map +1 -1
- package/dist/cli/commands/run.d.cts +17 -3
- package/dist/cli/commands/run.d.cts.map +1 -1
- package/dist/cli/commands/run.d.ts +17 -3
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +142 -78
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/index.cjs +671 -266
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +4 -16
- package/dist/cli/index.d.cts.map +1 -1
- package/dist/cli/index.d.ts +4 -16
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +664 -259
- package/dist/cli/index.js.map +1 -1
- package/dist/config/budget-schema.cjs +172 -0
- package/dist/config/budget-schema.cjs.map +1 -0
- package/dist/config/budget-schema.d.cts +59 -0
- package/dist/config/budget-schema.d.cts.map +1 -0
- package/dist/config/budget-schema.d.ts +59 -0
- package/dist/config/budget-schema.d.ts.map +1 -0
- package/dist/config/budget-schema.js +166 -0
- package/dist/config/budget-schema.js.map +1 -0
- package/dist/config/schema.cjs +182 -2
- package/dist/config/schema.cjs.map +1 -1
- package/dist/config/schema.d.cts +122 -3
- package/dist/config/schema.d.cts.map +1 -1
- package/dist/config/schema.d.ts +122 -3
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +180 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/constants.cjs +45 -2
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +41 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.ts +41 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +44 -1
- package/dist/constants.js.map +1 -1
- package/dist/core/engine.cjs +104 -15
- package/dist/core/engine.cjs.map +1 -1
- package/dist/core/engine.d.cts +7 -4
- package/dist/core/engine.d.cts.map +1 -1
- package/dist/core/engine.d.ts +7 -4
- package/dist/core/engine.d.ts.map +1 -1
- package/dist/core/engine.js +105 -16
- package/dist/core/engine.js.map +1 -1
- package/dist/core/output-path-resolver.cjs +41 -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 +37 -0
- package/dist/core/output-path-resolver.js.map +1 -0
- package/dist/errors/base.cjs +12 -3
- package/dist/errors/base.cjs.map +1 -1
- package/dist/errors/base.d.cts +7 -0
- package/dist/errors/base.d.cts.map +1 -1
- package/dist/errors/base.d.ts +7 -0
- package/dist/errors/base.d.ts.map +1 -1
- package/dist/errors/base.js +10 -2
- package/dist/errors/base.js.map +1 -1
- package/dist/errors/budget.cjs +37 -0
- package/dist/errors/budget.cjs.map +1 -0
- package/dist/errors/budget.d.cts +31 -0
- package/dist/errors/budget.d.cts.map +1 -0
- package/dist/errors/budget.d.ts +31 -0
- package/dist/errors/budget.d.ts.map +1 -0
- package/dist/errors/budget.js +33 -0
- package/dist/errors/budget.js.map +1 -0
- package/dist/errors/index.cjs +4 -1
- package/dist/errors/index.cjs.map +1 -1
- package/dist/errors/index.d.cts +1 -0
- package/dist/errors/index.d.cts.map +1 -1
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +2 -0
- package/dist/errors/index.js.map +1 -1
- 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 +27 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -5
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +10 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -9
- package/dist/index.js.map +1 -1
- package/dist/reporters/csv.cjs +39 -19
- package/dist/reporters/csv.cjs.map +1 -1
- package/dist/reporters/csv.d.cts +4 -7
- package/dist/reporters/csv.d.cts.map +1 -1
- package/dist/reporters/csv.d.ts +4 -7
- package/dist/reporters/csv.d.ts.map +1 -1
- package/dist/reporters/csv.js +38 -18
- package/dist/reporters/csv.js.map +1 -1
- package/dist/reporters/human.cjs +87 -99
- package/dist/reporters/human.cjs.map +1 -1
- package/dist/reporters/human.d.cts +15 -14
- package/dist/reporters/human.d.cts.map +1 -1
- package/dist/reporters/human.d.ts +15 -14
- package/dist/reporters/human.d.ts.map +1 -1
- package/dist/reporters/human.js +68 -80
- package/dist/reporters/human.js.map +1 -1
- package/dist/reporters/json.cjs +25 -50
- package/dist/reporters/json.cjs.map +1 -1
- package/dist/reporters/json.d.cts +3 -29
- package/dist/reporters/json.d.cts.map +1 -1
- package/dist/reporters/json.d.ts +3 -29
- package/dist/reporters/json.d.ts.map +1 -1
- package/dist/reporters/json.js +26 -51
- package/dist/reporters/json.js.map +1 -1
- package/dist/reporters/profile-human.cjs +149 -0
- package/dist/reporters/profile-human.cjs.map +1 -0
- package/dist/reporters/profile-human.d.cts +44 -0
- package/dist/reporters/profile-human.d.cts.map +1 -0
- package/dist/reporters/profile-human.d.ts +44 -0
- package/dist/reporters/profile-human.d.ts.map +1 -0
- package/dist/reporters/profile-human.js +142 -0
- package/dist/reporters/profile-human.js.map +1 -0
- package/dist/reporters/simple.cjs +66 -46
- package/dist/reporters/simple.cjs.map +1 -1
- package/dist/reporters/simple.d.cts +15 -15
- package/dist/reporters/simple.d.cts.map +1 -1
- package/dist/reporters/simple.d.ts +15 -15
- package/dist/reporters/simple.d.ts.map +1 -1
- package/dist/reporters/simple.js +65 -45
- package/dist/reporters/simple.js.map +1 -1
- package/dist/schema/modestbench-config.schema.json +153 -0
- package/dist/services/baseline-storage.cjs +151 -0
- package/dist/services/baseline-storage.cjs.map +1 -0
- package/dist/services/baseline-storage.d.cts +55 -0
- package/dist/services/baseline-storage.d.cts.map +1 -0
- package/dist/services/baseline-storage.d.ts +55 -0
- package/dist/services/baseline-storage.d.ts.map +1 -0
- package/dist/services/baseline-storage.js +147 -0
- package/dist/services/baseline-storage.js.map +1 -0
- package/dist/services/budget-evaluator.cjs +146 -0
- package/dist/services/budget-evaluator.cjs.map +1 -0
- package/dist/services/budget-evaluator.d.cts +29 -0
- package/dist/services/budget-evaluator.d.cts.map +1 -0
- package/dist/services/budget-evaluator.d.ts +29 -0
- package/dist/services/budget-evaluator.d.ts.map +1 -0
- package/dist/services/budget-evaluator.js +142 -0
- package/dist/services/budget-evaluator.js.map +1 -0
- package/dist/{config/manager.cjs → services/config-manager.cjs} +25 -11
- package/dist/services/config-manager.cjs.map +1 -0
- package/dist/{config/manager.d.cts → services/config-manager.d.cts} +7 -2
- package/dist/services/config-manager.d.cts.map +1 -0
- package/dist/{config/manager.d.ts → services/config-manager.d.ts} +7 -2
- package/dist/services/config-manager.d.ts.map +1 -0
- package/dist/{config/manager.js → services/config-manager.js} +25 -11
- package/dist/services/config-manager.js.map +1 -0
- package/dist/{core/loader.cjs → services/file-loader.cjs} +5 -8
- 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} +5 -8
- 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} +1 -1
- 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} +1 -1
- package/dist/services/history-storage.js.map +1 -0
- package/dist/services/profiler/profile-filter.cjs +113 -0
- package/dist/services/profiler/profile-filter.cjs.map +1 -0
- package/dist/services/profiler/profile-filter.d.cts +20 -0
- package/dist/services/profiler/profile-filter.d.cts.map +1 -0
- package/dist/services/profiler/profile-filter.d.ts +20 -0
- package/dist/services/profiler/profile-filter.d.ts.map +1 -0
- package/dist/services/profiler/profile-filter.js +109 -0
- package/dist/services/profiler/profile-filter.js.map +1 -0
- package/dist/services/profiler/profile-parser.cjs +139 -0
- package/dist/services/profiler/profile-parser.cjs.map +1 -0
- package/dist/services/profiler/profile-parser.d.cts +18 -0
- package/dist/services/profiler/profile-parser.d.cts.map +1 -0
- package/dist/services/profiler/profile-parser.d.ts +18 -0
- package/dist/services/profiler/profile-parser.d.ts.map +1 -0
- package/dist/services/profiler/profile-parser.js +132 -0
- package/dist/services/profiler/profile-parser.js.map +1 -0
- package/dist/services/profiler/profile-runner.cjs +90 -0
- package/dist/services/profiler/profile-runner.cjs.map +1 -0
- package/dist/services/profiler/profile-runner.d.cts +29 -0
- package/dist/services/profiler/profile-runner.d.cts.map +1 -0
- package/dist/services/profiler/profile-runner.d.ts +29 -0
- package/dist/services/profiler/profile-runner.d.ts.map +1 -0
- package/dist/services/profiler/profile-runner.js +86 -0
- package/dist/services/profiler/profile-runner.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} +19 -25
- package/dist/services/reporter-registry.cjs.map +1 -0
- package/dist/{reporters/registry.d.cts → services/reporter-registry.d.cts} +19 -41
- package/dist/services/reporter-registry.d.cts.map +1 -0
- package/dist/{reporters/registry.d.ts → services/reporter-registry.d.ts} +19 -41
- package/dist/services/reporter-registry.d.ts.map +1 -0
- package/dist/{reporters/registry.js → services/reporter-registry.js} +19 -25
- package/dist/services/reporter-registry.js.map +1 -0
- package/dist/types/budgets.cjs +8 -0
- package/dist/types/budgets.cjs.map +1 -0
- package/dist/types/budgets.d.cts +149 -0
- package/dist/types/budgets.d.cts.map +1 -0
- package/dist/types/budgets.d.ts +149 -0
- package/dist/types/budgets.d.ts.map +1 -0
- package/dist/types/budgets.js +7 -0
- package/dist/types/budgets.js.map +1 -0
- package/dist/types/cli.cjs +2 -11
- package/dist/types/cli.cjs.map +1 -1
- package/dist/types/cli.d.cts +3 -224
- package/dist/types/cli.d.cts.map +1 -1
- package/dist/types/cli.d.ts +3 -224
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/cli.js +2 -11
- package/dist/types/cli.js.map +1 -1
- package/dist/types/core.cjs +6 -1
- package/dist/types/core.cjs.map +1 -1
- package/dist/types/core.d.cts +13 -2
- package/dist/types/core.d.cts.map +1 -1
- package/dist/types/core.d.ts +13 -2
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/core.js +2 -1
- package/dist/types/core.js.map +1 -1
- package/dist/types/index.cjs +5 -0
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +2 -0
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/interfaces.d.cts +15 -8
- package/dist/types/interfaces.d.cts.map +1 -1
- package/dist/types/interfaces.d.ts +15 -8
- package/dist/types/interfaces.d.ts.map +1 -1
- package/dist/types/profiler.cjs +11 -0
- package/dist/types/profiler.cjs.map +1 -0
- package/dist/types/profiler.d.cts +100 -0
- package/dist/types/profiler.d.cts.map +1 -0
- package/dist/types/profiler.d.ts +100 -0
- package/dist/types/profiler.d.ts.map +1 -0
- package/dist/types/profiler.js +10 -0
- package/dist/types/profiler.js.map +1 -0
- package/dist/types/utility.cjs.map +1 -1
- package/dist/types/utility.d.cts +0 -8
- package/dist/types/utility.d.cts.map +1 -1
- package/dist/types/utility.d.ts +0 -8
- package/dist/types/utility.d.ts.map +1 -1
- package/dist/types/utility.js.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/dist/utils/identifiers.cjs +32 -0
- package/dist/utils/identifiers.cjs.map +1 -0
- package/dist/utils/identifiers.d.cts +32 -0
- package/dist/utils/identifiers.d.cts.map +1 -0
- package/dist/utils/identifiers.d.ts +32 -0
- package/dist/utils/identifiers.d.ts.map +1 -0
- package/dist/utils/identifiers.js +27 -0
- package/dist/utils/identifiers.js.map +1 -0
- package/dist/utils/package.cjs +40 -0
- package/dist/utils/package.cjs.map +1 -0
- package/dist/utils/package.d.cts +15 -0
- package/dist/utils/package.d.cts.map +1 -0
- package/dist/utils/package.d.ts +15 -0
- package/dist/utils/package.d.ts.map +1 -0
- package/dist/utils/package.js +33 -0
- package/dist/utils/package.js.map +1 -0
- package/dist/utils/type-guards.cjs +48 -0
- package/dist/utils/type-guards.cjs.map +1 -0
- package/dist/utils/type-guards.d.cts +22 -0
- package/dist/utils/type-guards.d.cts.map +1 -0
- package/dist/utils/type-guards.d.ts +22 -0
- package/dist/utils/type-guards.d.ts.map +1 -0
- package/dist/utils/type-guards.js +43 -0
- package/dist/utils/type-guards.js.map +1 -0
- package/package.json +14 -13
- package/src/bootstrap.ts +5 -5
- package/src/cli/commands/analyze.ts +101 -0
- package/src/cli/commands/baseline.ts +577 -0
- package/src/cli/commands/history.ts +194 -342
- package/src/cli/commands/init.ts +105 -183
- package/src/cli/commands/run.ts +186 -88
- package/src/cli/index.ts +731 -234
- package/src/config/budget-schema.ts +189 -0
- package/src/config/schema.ts +260 -1
- package/src/constants.ts +53 -1
- package/src/core/engine.ts +153 -14
- package/src/core/output-path-resolver.ts +46 -0
- package/src/errors/base.ts +11 -2
- package/src/errors/budget.ts +38 -0
- package/src/errors/index.ts +3 -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 +17 -12
- package/src/reporters/csv.ts +55 -26
- package/src/reporters/human.ts +90 -89
- package/src/reporters/json.ts +27 -72
- package/src/reporters/profile-human.ts +204 -0
- package/src/reporters/simple.ts +85 -54
- package/src/services/baseline-storage.ts +199 -0
- package/src/services/budget-evaluator.ts +182 -0
- package/src/{config/manager.ts → services/config-manager.ts} +24 -9
- package/src/{core/loader.ts → services/file-loader.ts} +4 -7
- 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/services/profiler/profile-filter.ts +143 -0
- package/src/services/profiler/profile-parser.ts +194 -0
- package/src/services/profiler/profile-runner.ts +121 -0
- package/src/{reporters/registry.ts → services/reporter-registry.ts} +46 -81
- package/src/types/budgets.ts +180 -0
- package/src/types/cli.ts +5 -235
- package/src/types/core.ts +50 -10
- package/src/types/index.ts +5 -0
- package/src/types/interfaces.ts +16 -6
- package/src/types/profiler.ts +132 -0
- package/src/types/utility.ts +0 -10
- package/src/utils/ansi.ts +59 -0
- package/src/utils/identifiers.ts +58 -0
- package/src/utils/package.ts +35 -0
- package/src/utils/type-guards.ts +51 -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/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/{storage/history.ts → services/history-storage.ts} +0 -0
- /package/src/{progress/manager.ts → services/progress-manager.ts} +0 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile Filter Service
|
|
3
|
+
*
|
|
4
|
+
* Filters and sorts profiled functions based on configuration. Implements smart
|
|
5
|
+
* detection to focus on user code by excluding node_modules and Node.js
|
|
6
|
+
* internals.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import { minimatch } from 'minimatch';
|
|
11
|
+
/**
|
|
12
|
+
* Filter profile data based on configuration
|
|
13
|
+
*
|
|
14
|
+
* @param data - Raw profile data
|
|
15
|
+
* @param config - Filter configuration
|
|
16
|
+
* @param packageRoot - Package root directory for smart detection
|
|
17
|
+
* @returns Filtered profile data
|
|
18
|
+
*/
|
|
19
|
+
export const filterProfile = (data, config, packageRoot) => {
|
|
20
|
+
let filtered = data.functions.filter((fn) => {
|
|
21
|
+
// Only JavaScript functions
|
|
22
|
+
if (fn.category !== 'JavaScript') {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
// Apply smart detection if enabled
|
|
26
|
+
if (config.smartDetection && !config.focus?.length) {
|
|
27
|
+
if (!isUserCode(fn.file, packageRoot)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Apply focus patterns (if provided, overrides smart detection)
|
|
32
|
+
if (config.focus?.length) {
|
|
33
|
+
if (!matchesAnyPattern(fn.file, config.focus)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Apply exclude patterns (always applied if provided)
|
|
38
|
+
if (config.exclude?.length) {
|
|
39
|
+
if (matchesAnyPattern(fn.file, config.exclude)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
});
|
|
45
|
+
// Apply percentage threshold
|
|
46
|
+
const minPercent = config.minExecutionPercent ?? 0.5;
|
|
47
|
+
filtered = filtered.filter((fn) => fn.percentage >= minPercent);
|
|
48
|
+
// Sort by percentage (highest first)
|
|
49
|
+
filtered.sort((a, b) => b.percentage - a.percentage);
|
|
50
|
+
// Limit to topN
|
|
51
|
+
const topN = config.topN ?? 25;
|
|
52
|
+
filtered = filtered.slice(0, topN);
|
|
53
|
+
// Group by file if requested
|
|
54
|
+
let groupedByFile;
|
|
55
|
+
if (config.groupByFile) {
|
|
56
|
+
groupedByFile = groupByFile(filtered);
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
functions: filtered,
|
|
60
|
+
groupedByFile,
|
|
61
|
+
summary: data.summary,
|
|
62
|
+
totalFiltered: data.functions.length,
|
|
63
|
+
totalShown: filtered.length,
|
|
64
|
+
totalTicks: data.totalTicks,
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Check if a file path is user code (not node_modules or internals)
|
|
69
|
+
*/
|
|
70
|
+
const isUserCode = (filePath, packageRoot) => {
|
|
71
|
+
// Exclude node_modules
|
|
72
|
+
if (filePath.includes('/node_modules/') ||
|
|
73
|
+
filePath.includes('\\node_modules\\')) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
// Exclude Node.js internals
|
|
77
|
+
if (filePath.startsWith('node:') || filePath.startsWith('internal/')) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
// Allow <unknown> files (could be eval'd code or other user code without file paths)
|
|
81
|
+
if (filePath === '<unknown>' || filePath === '[eval]') {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
// Must be within package root
|
|
85
|
+
return filePath.startsWith(packageRoot);
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Check if a file path matches any of the given glob patterns
|
|
89
|
+
*/
|
|
90
|
+
const matchesAnyPattern = (filePath, patterns) => {
|
|
91
|
+
return patterns.some((pattern) => minimatch(filePath, pattern));
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Group functions by file path
|
|
95
|
+
*/
|
|
96
|
+
const groupByFile = (functions) => {
|
|
97
|
+
const grouped = new Map();
|
|
98
|
+
for (const fn of functions) {
|
|
99
|
+
const existing = grouped.get(fn.file) || [];
|
|
100
|
+
existing.push(fn);
|
|
101
|
+
grouped.set(fn.file, existing);
|
|
102
|
+
}
|
|
103
|
+
// Sort functions within each file by percentage
|
|
104
|
+
for (const [, fns] of grouped.entries()) {
|
|
105
|
+
fns.sort((a, b) => b.percentage - a.percentage);
|
|
106
|
+
}
|
|
107
|
+
return grouped;
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=profile-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-filter.js","sourceRoot":"","sources":["../../../src/services/profiler/profile-filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Profile Parser Service
|
|
4
|
+
*
|
|
5
|
+
* Parses Chrome DevTools CPU profile format (*.cpuprofile files) generated by
|
|
6
|
+
* Node.js --cpu-prof flag. Extracts JavaScript function execution data
|
|
7
|
+
* including file paths, line numbers, hit counts, and percentages.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.parseProfile = void 0;
|
|
16
|
+
const promises_1 = require("node:fs/promises");
|
|
17
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
18
|
+
const node_url_1 = require("node:url");
|
|
19
|
+
/**
|
|
20
|
+
* Parse a CPU profile file
|
|
21
|
+
*
|
|
22
|
+
* @param profilePath - Path to *.cpuprofile file
|
|
23
|
+
* @returns Parsed profile data
|
|
24
|
+
*/
|
|
25
|
+
const parseProfile = async (profilePath) => {
|
|
26
|
+
// Read and parse JSON profile
|
|
27
|
+
const content = await (0, promises_1.readFile)(profilePath, 'utf-8');
|
|
28
|
+
const profile = JSON.parse(content);
|
|
29
|
+
// Extract functions and calculate statistics
|
|
30
|
+
return parseCpuProfile(profile, profilePath);
|
|
31
|
+
};
|
|
32
|
+
exports.parseProfile = parseProfile;
|
|
33
|
+
/**
|
|
34
|
+
* Parse CPU profile data structure
|
|
35
|
+
*/
|
|
36
|
+
const parseCpuProfile = (profile, profilePath) => {
|
|
37
|
+
const functions = [];
|
|
38
|
+
let totalTicks = 0;
|
|
39
|
+
// Calculate total ticks from all node hit counts
|
|
40
|
+
for (const node of profile.nodes) {
|
|
41
|
+
totalTicks += node.hitCount || 0;
|
|
42
|
+
}
|
|
43
|
+
// Extract function information from nodes with hit counts
|
|
44
|
+
for (const node of profile.nodes) {
|
|
45
|
+
const hitCount = node.hitCount || 0;
|
|
46
|
+
if (hitCount === 0) {
|
|
47
|
+
continue; // Skip nodes with no samples
|
|
48
|
+
}
|
|
49
|
+
const { callFrame } = node;
|
|
50
|
+
const percentage = totalTicks > 0 ? (hitCount / totalTicks) * 100 : 0;
|
|
51
|
+
// Parse file path from URL
|
|
52
|
+
const filePath = parseFileUrl(callFrame.url);
|
|
53
|
+
// Determine category based on URL
|
|
54
|
+
const category = determineCategory(callFrame.url);
|
|
55
|
+
functions.push({
|
|
56
|
+
category,
|
|
57
|
+
file: filePath,
|
|
58
|
+
line: callFrame.lineNumber >= 0 ? callFrame.lineNumber + 1 : null, // DevTools uses 0-based line numbers
|
|
59
|
+
name: callFrame.functionName || '(anonymous)',
|
|
60
|
+
percentage,
|
|
61
|
+
ticks: hitCount,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// Calculate summary statistics
|
|
65
|
+
const javascriptTicks = functions
|
|
66
|
+
.filter((fn) => fn.category === 'JavaScript')
|
|
67
|
+
.reduce((sum, fn) => sum + fn.ticks, 0);
|
|
68
|
+
const cppTicks = functions
|
|
69
|
+
.filter((fn) => fn.category === 'C++')
|
|
70
|
+
.reduce((sum, fn) => sum + fn.ticks, 0);
|
|
71
|
+
const summary = {
|
|
72
|
+
cppTicks,
|
|
73
|
+
gcTicks: 0, // CPU profiles don't separate GC
|
|
74
|
+
javascriptTicks,
|
|
75
|
+
sharedLibraryTicks: 0,
|
|
76
|
+
totalTicks,
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
functions,
|
|
80
|
+
logPath: profilePath,
|
|
81
|
+
summary,
|
|
82
|
+
totalTicks,
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Parse file URL from call frame
|
|
87
|
+
*/
|
|
88
|
+
const parseFileUrl = (url) => {
|
|
89
|
+
if (!url) {
|
|
90
|
+
return '<unknown>';
|
|
91
|
+
}
|
|
92
|
+
// Handle file:// URLs
|
|
93
|
+
if (url.startsWith('file://')) {
|
|
94
|
+
try {
|
|
95
|
+
return (0, node_url_1.fileURLToPath)(url);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// Fallback if URL is malformed
|
|
99
|
+
return node_path_1.default.normalize(url.replace('file://', ''));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Handle node: internal modules
|
|
103
|
+
if (url.startsWith('node:')) {
|
|
104
|
+
return url;
|
|
105
|
+
}
|
|
106
|
+
// Handle plain paths
|
|
107
|
+
return node_path_1.default.normalize(url);
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Determine function category based on URL
|
|
111
|
+
*/
|
|
112
|
+
const determineCategory = (url) => {
|
|
113
|
+
if (!url) {
|
|
114
|
+
return 'Unknown';
|
|
115
|
+
}
|
|
116
|
+
// Node.js internals and native modules
|
|
117
|
+
if (url.startsWith('node:') || url.includes('[native code]')) {
|
|
118
|
+
return 'C++';
|
|
119
|
+
}
|
|
120
|
+
// eval'd code is JavaScript
|
|
121
|
+
if (url === '[eval]') {
|
|
122
|
+
return 'JavaScript';
|
|
123
|
+
}
|
|
124
|
+
// JavaScript files
|
|
125
|
+
if (url.endsWith('.js') ||
|
|
126
|
+
url.endsWith('.mjs') ||
|
|
127
|
+
url.endsWith('.cjs') ||
|
|
128
|
+
url.endsWith('.ts') ||
|
|
129
|
+
url.endsWith('.mts') ||
|
|
130
|
+
url.endsWith('.cts')) {
|
|
131
|
+
return 'JavaScript';
|
|
132
|
+
}
|
|
133
|
+
// Default to JavaScript for file:// URLs
|
|
134
|
+
if (url.startsWith('file://')) {
|
|
135
|
+
return 'JavaScript';
|
|
136
|
+
}
|
|
137
|
+
return 'Unknown';
|
|
138
|
+
};
|
|
139
|
+
//# sourceMappingURL=profile-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-parser.js","sourceRoot":"","sources":["../../../src/services/profiler/profile-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile Parser Service
|
|
3
|
+
*
|
|
4
|
+
* Parses Chrome DevTools CPU profile format (*.cpuprofile files) generated by
|
|
5
|
+
* Node.js --cpu-prof flag. Extracts JavaScript function execution data
|
|
6
|
+
* including file paths, line numbers, hit counts, and percentages.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import type { RawProfileData } from "../../types/profiler.cjs";
|
|
11
|
+
/**
|
|
12
|
+
* Parse a CPU profile file
|
|
13
|
+
*
|
|
14
|
+
* @param profilePath - Path to *.cpuprofile file
|
|
15
|
+
* @returns Parsed profile data
|
|
16
|
+
*/
|
|
17
|
+
export declare const parseProfile: (profilePath: string) => Promise<RawProfileData>;
|
|
18
|
+
//# sourceMappingURL=profile-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-parser.d.ts","sourceRoot":"","sources":["../../../src/services/profiler/profile-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAGV,cAAc,EACf,iCAAgC;AA2BjC;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GACvB,aAAa,MAAM,KAClB,OAAO,CAAC,cAAc,CAOxB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile Parser Service
|
|
3
|
+
*
|
|
4
|
+
* Parses Chrome DevTools CPU profile format (*.cpuprofile files) generated by
|
|
5
|
+
* Node.js --cpu-prof flag. Extracts JavaScript function execution data
|
|
6
|
+
* including file paths, line numbers, hit counts, and percentages.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import type { RawProfileData } from "../../types/profiler.js";
|
|
11
|
+
/**
|
|
12
|
+
* Parse a CPU profile file
|
|
13
|
+
*
|
|
14
|
+
* @param profilePath - Path to *.cpuprofile file
|
|
15
|
+
* @returns Parsed profile data
|
|
16
|
+
*/
|
|
17
|
+
export declare const parseProfile: (profilePath: string) => Promise<RawProfileData>;
|
|
18
|
+
//# sourceMappingURL=profile-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-parser.d.ts","sourceRoot":"","sources":["../../../src/services/profiler/profile-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAGV,cAAc,EACf,gCAAgC;AA2BjC;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GACvB,aAAa,MAAM,KAClB,OAAO,CAAC,cAAc,CAOxB,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile Parser Service
|
|
3
|
+
*
|
|
4
|
+
* Parses Chrome DevTools CPU profile format (*.cpuprofile files) generated by
|
|
5
|
+
* Node.js --cpu-prof flag. Extracts JavaScript function execution data
|
|
6
|
+
* including file paths, line numbers, hit counts, and percentages.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import { readFile } from 'node:fs/promises';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
/**
|
|
14
|
+
* Parse a CPU profile file
|
|
15
|
+
*
|
|
16
|
+
* @param profilePath - Path to *.cpuprofile file
|
|
17
|
+
* @returns Parsed profile data
|
|
18
|
+
*/
|
|
19
|
+
export const parseProfile = async (profilePath) => {
|
|
20
|
+
// Read and parse JSON profile
|
|
21
|
+
const content = await readFile(profilePath, 'utf-8');
|
|
22
|
+
const profile = JSON.parse(content);
|
|
23
|
+
// Extract functions and calculate statistics
|
|
24
|
+
return parseCpuProfile(profile, profilePath);
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Parse CPU profile data structure
|
|
28
|
+
*/
|
|
29
|
+
const parseCpuProfile = (profile, profilePath) => {
|
|
30
|
+
const functions = [];
|
|
31
|
+
let totalTicks = 0;
|
|
32
|
+
// Calculate total ticks from all node hit counts
|
|
33
|
+
for (const node of profile.nodes) {
|
|
34
|
+
totalTicks += node.hitCount || 0;
|
|
35
|
+
}
|
|
36
|
+
// Extract function information from nodes with hit counts
|
|
37
|
+
for (const node of profile.nodes) {
|
|
38
|
+
const hitCount = node.hitCount || 0;
|
|
39
|
+
if (hitCount === 0) {
|
|
40
|
+
continue; // Skip nodes with no samples
|
|
41
|
+
}
|
|
42
|
+
const { callFrame } = node;
|
|
43
|
+
const percentage = totalTicks > 0 ? (hitCount / totalTicks) * 100 : 0;
|
|
44
|
+
// Parse file path from URL
|
|
45
|
+
const filePath = parseFileUrl(callFrame.url);
|
|
46
|
+
// Determine category based on URL
|
|
47
|
+
const category = determineCategory(callFrame.url);
|
|
48
|
+
functions.push({
|
|
49
|
+
category,
|
|
50
|
+
file: filePath,
|
|
51
|
+
line: callFrame.lineNumber >= 0 ? callFrame.lineNumber + 1 : null, // DevTools uses 0-based line numbers
|
|
52
|
+
name: callFrame.functionName || '(anonymous)',
|
|
53
|
+
percentage,
|
|
54
|
+
ticks: hitCount,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// Calculate summary statistics
|
|
58
|
+
const javascriptTicks = functions
|
|
59
|
+
.filter((fn) => fn.category === 'JavaScript')
|
|
60
|
+
.reduce((sum, fn) => sum + fn.ticks, 0);
|
|
61
|
+
const cppTicks = functions
|
|
62
|
+
.filter((fn) => fn.category === 'C++')
|
|
63
|
+
.reduce((sum, fn) => sum + fn.ticks, 0);
|
|
64
|
+
const summary = {
|
|
65
|
+
cppTicks,
|
|
66
|
+
gcTicks: 0, // CPU profiles don't separate GC
|
|
67
|
+
javascriptTicks,
|
|
68
|
+
sharedLibraryTicks: 0,
|
|
69
|
+
totalTicks,
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
functions,
|
|
73
|
+
logPath: profilePath,
|
|
74
|
+
summary,
|
|
75
|
+
totalTicks,
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Parse file URL from call frame
|
|
80
|
+
*/
|
|
81
|
+
const parseFileUrl = (url) => {
|
|
82
|
+
if (!url) {
|
|
83
|
+
return '<unknown>';
|
|
84
|
+
}
|
|
85
|
+
// Handle file:// URLs
|
|
86
|
+
if (url.startsWith('file://')) {
|
|
87
|
+
try {
|
|
88
|
+
return fileURLToPath(url);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// Fallback if URL is malformed
|
|
92
|
+
return path.normalize(url.replace('file://', ''));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Handle node: internal modules
|
|
96
|
+
if (url.startsWith('node:')) {
|
|
97
|
+
return url;
|
|
98
|
+
}
|
|
99
|
+
// Handle plain paths
|
|
100
|
+
return path.normalize(url);
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Determine function category based on URL
|
|
104
|
+
*/
|
|
105
|
+
const determineCategory = (url) => {
|
|
106
|
+
if (!url) {
|
|
107
|
+
return 'Unknown';
|
|
108
|
+
}
|
|
109
|
+
// Node.js internals and native modules
|
|
110
|
+
if (url.startsWith('node:') || url.includes('[native code]')) {
|
|
111
|
+
return 'C++';
|
|
112
|
+
}
|
|
113
|
+
// eval'd code is JavaScript
|
|
114
|
+
if (url === '[eval]') {
|
|
115
|
+
return 'JavaScript';
|
|
116
|
+
}
|
|
117
|
+
// JavaScript files
|
|
118
|
+
if (url.endsWith('.js') ||
|
|
119
|
+
url.endsWith('.mjs') ||
|
|
120
|
+
url.endsWith('.cjs') ||
|
|
121
|
+
url.endsWith('.ts') ||
|
|
122
|
+
url.endsWith('.mts') ||
|
|
123
|
+
url.endsWith('.cts')) {
|
|
124
|
+
return 'JavaScript';
|
|
125
|
+
}
|
|
126
|
+
// Default to JavaScript for file:// URLs
|
|
127
|
+
if (url.startsWith('file://')) {
|
|
128
|
+
return 'JavaScript';
|
|
129
|
+
}
|
|
130
|
+
return 'Unknown';
|
|
131
|
+
};
|
|
132
|
+
//# sourceMappingURL=profile-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-parser.js","sourceRoot":"","sources":["../../../src/services/profiler/profile-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Profile Runner Service
|
|
4
|
+
*
|
|
5
|
+
* Executes commands with Node.js CPU profiling enabled and captures profiler
|
|
6
|
+
* output to *.cpuprofile files in .modestbench/profiles/.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.runWithProfiling = void 0;
|
|
12
|
+
const glob_1 = require("glob");
|
|
13
|
+
const node_child_process_1 = require("node:child_process");
|
|
14
|
+
const promises_1 = require("node:fs/promises");
|
|
15
|
+
const node_path_1 = require("node:path");
|
|
16
|
+
/**
|
|
17
|
+
* Run a command with Node.js profiling enabled
|
|
18
|
+
*
|
|
19
|
+
* @param command - Command to run (e.g., "npm test")
|
|
20
|
+
* @param options - Execution options
|
|
21
|
+
* @returns Path to generated *.cpuprofile file
|
|
22
|
+
*/
|
|
23
|
+
const runWithProfiling = async (command, options = {}) => {
|
|
24
|
+
const cwd = options.cwd || process.cwd();
|
|
25
|
+
// Create profiles directory
|
|
26
|
+
const profilesDir = (0, node_path_1.join)(cwd, '.modestbench', 'profiles');
|
|
27
|
+
await (0, promises_1.mkdir)(profilesDir, { recursive: true });
|
|
28
|
+
// Run command with NODE_OPTIONS="--cpu-prof --cpu-prof-dir=..."
|
|
29
|
+
const proc = (0, node_child_process_1.spawn)(command, {
|
|
30
|
+
cwd,
|
|
31
|
+
env: {
|
|
32
|
+
...process.env,
|
|
33
|
+
...options.env,
|
|
34
|
+
NODE_OPTIONS: `--cpu-prof --cpu-prof-dir=${profilesDir}`,
|
|
35
|
+
},
|
|
36
|
+
shell: true,
|
|
37
|
+
stdio: 'inherit',
|
|
38
|
+
});
|
|
39
|
+
// Wait for process to complete
|
|
40
|
+
await new Promise((resolve, reject) => {
|
|
41
|
+
const timeout = options.timeout
|
|
42
|
+
? setTimeout(() => {
|
|
43
|
+
proc.kill();
|
|
44
|
+
reject(new Error(`Profile command timed out after ${options.timeout}ms`));
|
|
45
|
+
}, options.timeout)
|
|
46
|
+
: null;
|
|
47
|
+
proc.on('close', (code) => {
|
|
48
|
+
if (timeout) {
|
|
49
|
+
clearTimeout(timeout);
|
|
50
|
+
}
|
|
51
|
+
if (code === 0 || code === null) {
|
|
52
|
+
resolve();
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
reject(new Error(`Profile command exited with code ${code}`));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
proc.on('error', (err) => {
|
|
59
|
+
if (timeout) {
|
|
60
|
+
clearTimeout(timeout);
|
|
61
|
+
}
|
|
62
|
+
reject(err);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
// Find generated *.cpuprofile file in profiles directory
|
|
66
|
+
const profileFiles = await (0, glob_1.glob)('*.cpuprofile', { cwd: profilesDir });
|
|
67
|
+
if (profileFiles.length === 0) {
|
|
68
|
+
throw new Error('No CPU profile generated. Ensure the command runs Node.js code.');
|
|
69
|
+
}
|
|
70
|
+
// Return most recent profile file
|
|
71
|
+
return await getMostRecentFile(profileFiles, profilesDir);
|
|
72
|
+
};
|
|
73
|
+
exports.runWithProfiling = runWithProfiling;
|
|
74
|
+
/**
|
|
75
|
+
* Get the most recently modified file from a list
|
|
76
|
+
*/
|
|
77
|
+
const getMostRecentFile = async (files, cwd) => {
|
|
78
|
+
let mostRecent = files[0];
|
|
79
|
+
let mostRecentTime = (await (0, promises_1.stat)(`${cwd}/${mostRecent}`)).mtimeMs;
|
|
80
|
+
for (const file of files.slice(1)) {
|
|
81
|
+
const filePath = `${cwd}/${file}`;
|
|
82
|
+
const fileTime = (await (0, promises_1.stat)(filePath)).mtimeMs;
|
|
83
|
+
if (fileTime > mostRecentTime) {
|
|
84
|
+
mostRecent = file;
|
|
85
|
+
mostRecentTime = fileTime;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return `${cwd}/${mostRecent}`;
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=profile-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-runner.js","sourceRoot":"","sources":["../../../src/services/profiler/profile-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile Runner Service
|
|
3
|
+
*
|
|
4
|
+
* Executes commands with Node.js CPU profiling enabled and captures profiler
|
|
5
|
+
* output to *.cpuprofile files in .modestbench/profiles/.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Options for running with profiling
|
|
11
|
+
*/
|
|
12
|
+
interface RunOptions {
|
|
13
|
+
/** Working directory */
|
|
14
|
+
cwd?: string;
|
|
15
|
+
/** Environment variables */
|
|
16
|
+
env?: NodeJS.ProcessEnv;
|
|
17
|
+
/** Timeout in milliseconds */
|
|
18
|
+
timeout?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Run a command with Node.js profiling enabled
|
|
22
|
+
*
|
|
23
|
+
* @param command - Command to run (e.g., "npm test")
|
|
24
|
+
* @param options - Execution options
|
|
25
|
+
* @returns Path to generated *.cpuprofile file
|
|
26
|
+
*/
|
|
27
|
+
export declare const runWithProfiling: (command: string, options?: RunOptions) => Promise<string>;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=profile-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-runner.d.ts","sourceRoot":"","sources":["../../../src/services/profiler/profile-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH;;GAEG;AACH,UAAU,UAAU;IAClB,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,4BAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAExB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,EACf,UAAS,UAAe,KACvB,OAAO,CAAC,MAAM,CA4DhB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile Runner Service
|
|
3
|
+
*
|
|
4
|
+
* Executes commands with Node.js CPU profiling enabled and captures profiler
|
|
5
|
+
* output to *.cpuprofile files in .modestbench/profiles/.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Options for running with profiling
|
|
11
|
+
*/
|
|
12
|
+
interface RunOptions {
|
|
13
|
+
/** Working directory */
|
|
14
|
+
cwd?: string;
|
|
15
|
+
/** Environment variables */
|
|
16
|
+
env?: NodeJS.ProcessEnv;
|
|
17
|
+
/** Timeout in milliseconds */
|
|
18
|
+
timeout?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Run a command with Node.js profiling enabled
|
|
22
|
+
*
|
|
23
|
+
* @param command - Command to run (e.g., "npm test")
|
|
24
|
+
* @param options - Execution options
|
|
25
|
+
* @returns Path to generated *.cpuprofile file
|
|
26
|
+
*/
|
|
27
|
+
export declare const runWithProfiling: (command: string, options?: RunOptions) => Promise<string>;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=profile-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-runner.d.ts","sourceRoot":"","sources":["../../../src/services/profiler/profile-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH;;GAEG;AACH,UAAU,UAAU;IAClB,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,4BAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAExB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,EACf,UAAS,UAAe,KACvB,OAAO,CAAC,MAAM,CA4DhB,CAAC"}
|