modestbench 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +131 -34
  3. package/dist/cli/commands/analyze.cjs +60 -0
  4. package/dist/cli/commands/analyze.cjs.map +1 -0
  5. package/dist/cli/commands/analyze.d.cts +35 -0
  6. package/dist/cli/commands/analyze.d.cts.map +1 -0
  7. package/dist/cli/commands/analyze.d.ts +35 -0
  8. package/dist/cli/commands/analyze.d.ts.map +1 -0
  9. package/dist/cli/commands/analyze.js +56 -0
  10. package/dist/cli/commands/analyze.js.map +1 -0
  11. package/dist/cli/commands/baseline.cjs +404 -0
  12. package/dist/cli/commands/baseline.cjs.map +1 -0
  13. package/dist/cli/commands/baseline.d.cts +72 -0
  14. package/dist/cli/commands/baseline.d.cts.map +1 -0
  15. package/dist/cli/commands/baseline.d.ts +72 -0
  16. package/dist/cli/commands/baseline.d.ts.map +1 -0
  17. package/dist/cli/commands/baseline.js +396 -0
  18. package/dist/cli/commands/baseline.js.map +1 -0
  19. package/dist/cli/commands/history.d.cts +1 -1
  20. package/dist/cli/commands/history.d.cts.map +1 -1
  21. package/dist/cli/commands/history.d.ts +1 -1
  22. package/dist/cli/commands/history.d.ts.map +1 -1
  23. package/dist/cli/commands/init.cjs +99 -166
  24. package/dist/cli/commands/init.cjs.map +1 -1
  25. package/dist/cli/commands/init.d.cts +4 -4
  26. package/dist/cli/commands/init.d.cts.map +1 -1
  27. package/dist/cli/commands/init.d.ts +4 -4
  28. package/dist/cli/commands/init.d.ts.map +1 -1
  29. package/dist/cli/commands/init.js +99 -166
  30. package/dist/cli/commands/init.js.map +1 -1
  31. package/dist/cli/commands/run.cjs +146 -127
  32. package/dist/cli/commands/run.cjs.map +1 -1
  33. package/dist/cli/commands/run.d.cts +16 -3
  34. package/dist/cli/commands/run.d.cts.map +1 -1
  35. package/dist/cli/commands/run.d.ts +16 -3
  36. package/dist/cli/commands/run.d.ts.map +1 -1
  37. package/dist/cli/commands/run.js +145 -93
  38. package/dist/cli/commands/run.js.map +1 -1
  39. package/dist/cli/index.cjs +583 -394
  40. package/dist/cli/index.cjs.map +1 -1
  41. package/dist/cli/index.d.cts +4 -16
  42. package/dist/cli/index.d.cts.map +1 -1
  43. package/dist/cli/index.d.ts +4 -16
  44. package/dist/cli/index.d.ts.map +1 -1
  45. package/dist/cli/index.js +575 -386
  46. package/dist/cli/index.js.map +1 -1
  47. package/dist/config/budget-schema.cjs +172 -0
  48. package/dist/config/budget-schema.cjs.map +1 -0
  49. package/dist/config/budget-schema.d.cts +59 -0
  50. package/dist/config/budget-schema.d.cts.map +1 -0
  51. package/dist/config/budget-schema.d.ts +59 -0
  52. package/dist/config/budget-schema.d.ts.map +1 -0
  53. package/dist/config/budget-schema.js +166 -0
  54. package/dist/config/budget-schema.js.map +1 -0
  55. package/dist/config/schema.cjs +182 -2
  56. package/dist/config/schema.cjs.map +1 -1
  57. package/dist/config/schema.d.cts +122 -3
  58. package/dist/config/schema.d.cts.map +1 -1
  59. package/dist/config/schema.d.ts +122 -3
  60. package/dist/config/schema.d.ts.map +1 -1
  61. package/dist/config/schema.js +180 -1
  62. package/dist/config/schema.js.map +1 -1
  63. package/dist/constants.cjs +45 -2
  64. package/dist/constants.cjs.map +1 -1
  65. package/dist/constants.d.cts +41 -0
  66. package/dist/constants.d.cts.map +1 -1
  67. package/dist/constants.d.ts +41 -0
  68. package/dist/constants.d.ts.map +1 -1
  69. package/dist/constants.js +44 -1
  70. package/dist/constants.js.map +1 -1
  71. package/dist/core/engine.cjs +114 -23
  72. package/dist/core/engine.cjs.map +1 -1
  73. package/dist/core/engine.d.cts +7 -7
  74. package/dist/core/engine.d.cts.map +1 -1
  75. package/dist/core/engine.d.ts +7 -7
  76. package/dist/core/engine.d.ts.map +1 -1
  77. package/dist/core/engine.js +115 -24
  78. package/dist/core/engine.js.map +1 -1
  79. package/dist/core/engines/accurate-engine.cjs +171 -36
  80. package/dist/core/engines/accurate-engine.cjs.map +1 -1
  81. package/dist/core/engines/accurate-engine.d.cts +5 -0
  82. package/dist/core/engines/accurate-engine.d.cts.map +1 -1
  83. package/dist/core/engines/accurate-engine.d.ts +5 -0
  84. package/dist/core/engines/accurate-engine.d.ts.map +1 -1
  85. package/dist/core/engines/accurate-engine.js +171 -36
  86. package/dist/core/engines/accurate-engine.js.map +1 -1
  87. package/dist/core/engines/tinybench-engine.cjs +3 -2
  88. package/dist/core/engines/tinybench-engine.cjs.map +1 -1
  89. package/dist/core/engines/tinybench-engine.d.cts.map +1 -1
  90. package/dist/core/engines/tinybench-engine.d.ts.map +1 -1
  91. package/dist/core/engines/tinybench-engine.js +3 -2
  92. package/dist/core/engines/tinybench-engine.js.map +1 -1
  93. package/dist/core/output-path-resolver.cjs +8 -1
  94. package/dist/core/output-path-resolver.cjs.map +1 -1
  95. package/dist/core/output-path-resolver.d.cts.map +1 -1
  96. package/dist/core/output-path-resolver.d.ts.map +1 -1
  97. package/dist/core/output-path-resolver.js +9 -2
  98. package/dist/core/output-path-resolver.js.map +1 -1
  99. package/dist/errors/base.cjs +12 -3
  100. package/dist/errors/base.cjs.map +1 -1
  101. package/dist/errors/base.d.cts +7 -0
  102. package/dist/errors/base.d.cts.map +1 -1
  103. package/dist/errors/base.d.ts +7 -0
  104. package/dist/errors/base.d.ts.map +1 -1
  105. package/dist/errors/base.js +10 -2
  106. package/dist/errors/base.js.map +1 -1
  107. package/dist/errors/budget.cjs +37 -0
  108. package/dist/errors/budget.cjs.map +1 -0
  109. package/dist/errors/budget.d.cts +31 -0
  110. package/dist/errors/budget.d.cts.map +1 -0
  111. package/dist/errors/budget.d.ts +31 -0
  112. package/dist/errors/budget.d.ts.map +1 -0
  113. package/dist/errors/budget.js +33 -0
  114. package/dist/errors/budget.js.map +1 -0
  115. package/dist/errors/index.cjs +4 -1
  116. package/dist/errors/index.cjs.map +1 -1
  117. package/dist/errors/index.d.cts +1 -0
  118. package/dist/errors/index.d.cts.map +1 -1
  119. package/dist/errors/index.d.ts +1 -0
  120. package/dist/errors/index.d.ts.map +1 -1
  121. package/dist/errors/index.js +2 -0
  122. package/dist/errors/index.js.map +1 -1
  123. package/dist/index.cjs +13 -1
  124. package/dist/index.cjs.map +1 -1
  125. package/dist/index.d.cts +5 -0
  126. package/dist/index.d.cts.map +1 -1
  127. package/dist/index.d.ts +5 -0
  128. package/dist/index.d.ts.map +1 -1
  129. package/dist/index.js +7 -0
  130. package/dist/index.js.map +1 -1
  131. package/dist/reporters/csv.cjs +37 -17
  132. package/dist/reporters/csv.cjs.map +1 -1
  133. package/dist/reporters/csv.d.cts +3 -6
  134. package/dist/reporters/csv.d.cts.map +1 -1
  135. package/dist/reporters/csv.d.ts +3 -6
  136. package/dist/reporters/csv.d.ts.map +1 -1
  137. package/dist/reporters/csv.js +37 -17
  138. package/dist/reporters/csv.js.map +1 -1
  139. package/dist/reporters/human.cjs +290 -67
  140. package/dist/reporters/human.cjs.map +1 -1
  141. package/dist/reporters/human.d.cts +25 -13
  142. package/dist/reporters/human.d.cts.map +1 -1
  143. package/dist/reporters/human.d.ts +25 -13
  144. package/dist/reporters/human.d.ts.map +1 -1
  145. package/dist/reporters/human.js +290 -67
  146. package/dist/reporters/human.js.map +1 -1
  147. package/dist/reporters/json.cjs +23 -48
  148. package/dist/reporters/json.cjs.map +1 -1
  149. package/dist/reporters/json.d.cts +2 -28
  150. package/dist/reporters/json.d.cts.map +1 -1
  151. package/dist/reporters/json.d.ts +2 -28
  152. package/dist/reporters/json.d.ts.map +1 -1
  153. package/dist/reporters/json.js +25 -50
  154. package/dist/reporters/json.js.map +1 -1
  155. package/dist/reporters/profile-human.cjs +154 -0
  156. package/dist/reporters/profile-human.cjs.map +1 -0
  157. package/dist/reporters/profile-human.d.cts +44 -0
  158. package/dist/reporters/profile-human.d.cts.map +1 -0
  159. package/dist/reporters/profile-human.d.ts +44 -0
  160. package/dist/reporters/profile-human.d.ts.map +1 -0
  161. package/dist/reporters/profile-human.js +147 -0
  162. package/dist/reporters/profile-human.js.map +1 -0
  163. package/dist/reporters/simple.cjs +67 -45
  164. package/dist/reporters/simple.cjs.map +1 -1
  165. package/dist/reporters/simple.d.cts +14 -14
  166. package/dist/reporters/simple.d.cts.map +1 -1
  167. package/dist/reporters/simple.d.ts +14 -14
  168. package/dist/reporters/simple.d.ts.map +1 -1
  169. package/dist/reporters/simple.js +67 -45
  170. package/dist/reporters/simple.js.map +1 -1
  171. package/dist/schema/modestbench-config.schema.json +153 -0
  172. package/dist/services/baseline-storage.cjs +151 -0
  173. package/dist/services/baseline-storage.cjs.map +1 -0
  174. package/dist/services/baseline-storage.d.cts +55 -0
  175. package/dist/services/baseline-storage.d.cts.map +1 -0
  176. package/dist/services/baseline-storage.d.ts +55 -0
  177. package/dist/services/baseline-storage.d.ts.map +1 -0
  178. package/dist/services/baseline-storage.js +147 -0
  179. package/dist/services/baseline-storage.js.map +1 -0
  180. package/dist/services/budget-evaluator.cjs +146 -0
  181. package/dist/services/budget-evaluator.cjs.map +1 -0
  182. package/dist/services/budget-evaluator.d.cts +29 -0
  183. package/dist/services/budget-evaluator.d.cts.map +1 -0
  184. package/dist/services/budget-evaluator.d.ts +29 -0
  185. package/dist/services/budget-evaluator.d.ts.map +1 -0
  186. package/dist/services/budget-evaluator.js +142 -0
  187. package/dist/services/budget-evaluator.js.map +1 -0
  188. package/dist/services/config-manager.cjs +24 -10
  189. package/dist/services/config-manager.cjs.map +1 -1
  190. package/dist/services/config-manager.d.cts +6 -1
  191. package/dist/services/config-manager.d.cts.map +1 -1
  192. package/dist/services/config-manager.d.ts +6 -1
  193. package/dist/services/config-manager.d.ts.map +1 -1
  194. package/dist/services/config-manager.js +24 -10
  195. package/dist/services/config-manager.js.map +1 -1
  196. package/dist/services/file-loader.cjs +3 -6
  197. package/dist/services/file-loader.cjs.map +1 -1
  198. package/dist/services/file-loader.d.cts.map +1 -1
  199. package/dist/services/file-loader.d.ts.map +1 -1
  200. package/dist/services/file-loader.js +3 -6
  201. package/dist/services/file-loader.js.map +1 -1
  202. package/dist/services/profiler/profile-filter.cjs +116 -0
  203. package/dist/services/profiler/profile-filter.cjs.map +1 -0
  204. package/dist/services/profiler/profile-filter.d.cts +20 -0
  205. package/dist/services/profiler/profile-filter.d.cts.map +1 -0
  206. package/dist/services/profiler/profile-filter.d.ts +20 -0
  207. package/dist/services/profiler/profile-filter.d.ts.map +1 -0
  208. package/dist/services/profiler/profile-filter.js +112 -0
  209. package/dist/services/profiler/profile-filter.js.map +1 -0
  210. package/dist/services/profiler/profile-parser.cjs +139 -0
  211. package/dist/services/profiler/profile-parser.cjs.map +1 -0
  212. package/dist/services/profiler/profile-parser.d.cts +18 -0
  213. package/dist/services/profiler/profile-parser.d.cts.map +1 -0
  214. package/dist/services/profiler/profile-parser.d.ts +18 -0
  215. package/dist/services/profiler/profile-parser.d.ts.map +1 -0
  216. package/dist/services/profiler/profile-parser.js +132 -0
  217. package/dist/services/profiler/profile-parser.js.map +1 -0
  218. package/dist/services/profiler/profile-runner.cjs +90 -0
  219. package/dist/services/profiler/profile-runner.cjs.map +1 -0
  220. package/dist/services/profiler/profile-runner.d.cts +29 -0
  221. package/dist/services/profiler/profile-runner.d.cts.map +1 -0
  222. package/dist/services/profiler/profile-runner.d.ts +29 -0
  223. package/dist/services/profiler/profile-runner.d.ts.map +1 -0
  224. package/dist/services/profiler/profile-runner.js +86 -0
  225. package/dist/services/profiler/profile-runner.js.map +1 -0
  226. package/dist/services/progress-manager.cjs +10 -2
  227. package/dist/services/progress-manager.cjs.map +1 -1
  228. package/dist/services/progress-manager.d.cts +2 -0
  229. package/dist/services/progress-manager.d.cts.map +1 -1
  230. package/dist/services/progress-manager.d.ts +2 -0
  231. package/dist/services/progress-manager.d.ts.map +1 -1
  232. package/dist/services/progress-manager.js +10 -2
  233. package/dist/services/progress-manager.js.map +1 -1
  234. package/dist/services/reporter-registry.cjs +18 -24
  235. package/dist/services/reporter-registry.cjs.map +1 -1
  236. package/dist/services/reporter-registry.d.cts +18 -40
  237. package/dist/services/reporter-registry.d.cts.map +1 -1
  238. package/dist/services/reporter-registry.d.ts +18 -40
  239. package/dist/services/reporter-registry.d.ts.map +1 -1
  240. package/dist/services/reporter-registry.js +18 -24
  241. package/dist/services/reporter-registry.js.map +1 -1
  242. package/dist/types/budgets.cjs +8 -0
  243. package/dist/types/budgets.cjs.map +1 -0
  244. package/dist/types/budgets.d.cts +149 -0
  245. package/dist/types/budgets.d.cts.map +1 -0
  246. package/dist/types/budgets.d.ts +149 -0
  247. package/dist/types/budgets.d.ts.map +1 -0
  248. package/dist/types/budgets.js +7 -0
  249. package/dist/types/budgets.js.map +1 -0
  250. package/dist/types/cli.cjs +2 -11
  251. package/dist/types/cli.cjs.map +1 -1
  252. package/dist/types/cli.d.cts +3 -227
  253. package/dist/types/cli.d.cts.map +1 -1
  254. package/dist/types/cli.d.ts +3 -227
  255. package/dist/types/cli.d.ts.map +1 -1
  256. package/dist/types/cli.js +2 -11
  257. package/dist/types/cli.js.map +1 -1
  258. package/dist/types/core.cjs +6 -1
  259. package/dist/types/core.cjs.map +1 -1
  260. package/dist/types/core.d.cts +15 -2
  261. package/dist/types/core.d.cts.map +1 -1
  262. package/dist/types/core.d.ts +15 -2
  263. package/dist/types/core.d.ts.map +1 -1
  264. package/dist/types/core.js +2 -1
  265. package/dist/types/core.js.map +1 -1
  266. package/dist/types/index.cjs +5 -0
  267. package/dist/types/index.cjs.map +1 -1
  268. package/dist/types/index.d.cts +2 -0
  269. package/dist/types/index.d.cts.map +1 -1
  270. package/dist/types/index.d.ts +2 -0
  271. package/dist/types/index.d.ts.map +1 -1
  272. package/dist/types/index.js +2 -0
  273. package/dist/types/index.js.map +1 -1
  274. package/dist/types/interfaces.d.cts +19 -8
  275. package/dist/types/interfaces.d.cts.map +1 -1
  276. package/dist/types/interfaces.d.ts +19 -8
  277. package/dist/types/interfaces.d.ts.map +1 -1
  278. package/dist/types/profiler.cjs +11 -0
  279. package/dist/types/profiler.cjs.map +1 -0
  280. package/dist/types/profiler.d.cts +102 -0
  281. package/dist/types/profiler.d.cts.map +1 -0
  282. package/dist/types/profiler.d.ts +102 -0
  283. package/dist/types/profiler.d.ts.map +1 -0
  284. package/dist/types/profiler.js +10 -0
  285. package/dist/types/profiler.js.map +1 -0
  286. package/dist/types/utility.cjs.map +1 -1
  287. package/dist/types/utility.d.cts +0 -8
  288. package/dist/types/utility.d.cts.map +1 -1
  289. package/dist/types/utility.d.ts +0 -8
  290. package/dist/types/utility.d.ts.map +1 -1
  291. package/dist/types/utility.js.map +1 -1
  292. package/dist/utils/identifiers.cjs +32 -0
  293. package/dist/utils/identifiers.cjs.map +1 -0
  294. package/dist/utils/identifiers.d.cts +32 -0
  295. package/dist/utils/identifiers.d.cts.map +1 -0
  296. package/dist/utils/identifiers.d.ts +32 -0
  297. package/dist/utils/identifiers.d.ts.map +1 -0
  298. package/dist/utils/identifiers.js +27 -0
  299. package/dist/utils/identifiers.js.map +1 -0
  300. package/dist/utils/package.cjs +40 -0
  301. package/dist/utils/package.cjs.map +1 -0
  302. package/dist/utils/package.d.cts +15 -0
  303. package/dist/utils/package.d.cts.map +1 -0
  304. package/dist/utils/package.d.ts +15 -0
  305. package/dist/utils/package.d.ts.map +1 -0
  306. package/dist/utils/package.js +33 -0
  307. package/dist/utils/package.js.map +1 -0
  308. package/dist/utils/type-guards.cjs +48 -0
  309. package/dist/utils/type-guards.cjs.map +1 -0
  310. package/dist/utils/type-guards.d.cts +22 -0
  311. package/dist/utils/type-guards.d.cts.map +1 -0
  312. package/dist/utils/type-guards.d.ts +22 -0
  313. package/dist/utils/type-guards.d.ts.map +1 -0
  314. package/dist/utils/type-guards.js +43 -0
  315. package/dist/utils/type-guards.js.map +1 -0
  316. package/package.json +18 -19
  317. package/src/cli/commands/analyze.ts +101 -0
  318. package/src/cli/commands/baseline.ts +577 -0
  319. package/src/cli/commands/history.ts +1 -1
  320. package/src/cli/commands/init.ts +116 -194
  321. package/src/cli/commands/run.ts +183 -113
  322. package/src/cli/index.ts +425 -183
  323. package/src/config/budget-schema.ts +189 -0
  324. package/src/config/schema.ts +260 -1
  325. package/src/constants.ts +53 -1
  326. package/src/core/engine.ts +169 -22
  327. package/src/core/engines/accurate-engine.ts +195 -44
  328. package/src/core/engines/tinybench-engine.ts +3 -2
  329. package/src/core/output-path-resolver.ts +10 -2
  330. package/src/errors/base.ts +11 -2
  331. package/src/errors/budget.ts +38 -0
  332. package/src/errors/index.ts +3 -0
  333. package/src/index.ts +9 -0
  334. package/src/reporters/csv.ts +54 -25
  335. package/src/reporters/human.ts +434 -115
  336. package/src/reporters/json.ts +26 -71
  337. package/src/reporters/profile-human.ts +210 -0
  338. package/src/reporters/simple.ts +88 -54
  339. package/src/services/baseline-storage.ts +199 -0
  340. package/src/services/budget-evaluator.ts +182 -0
  341. package/src/services/config-manager.ts +24 -9
  342. package/src/services/file-loader.ts +3 -6
  343. package/src/services/profiler/profile-filter.ts +147 -0
  344. package/src/services/profiler/profile-parser.ts +194 -0
  345. package/src/services/profiler/profile-runner.ts +121 -0
  346. package/src/services/progress-manager.ts +12 -2
  347. package/src/services/reporter-registry.ts +46 -81
  348. package/src/types/budgets.ts +180 -0
  349. package/src/types/cli.ts +5 -238
  350. package/src/types/core.ts +52 -10
  351. package/src/types/index.ts +5 -0
  352. package/src/types/interfaces.ts +24 -6
  353. package/src/types/profiler.ts +135 -0
  354. package/src/types/utility.ts +0 -10
  355. package/src/utils/identifiers.ts +58 -0
  356. package/src/utils/package.ts +35 -0
  357. package/src/utils/type-guards.ts +51 -0
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ /**
3
+ * Profile Filter Service
4
+ *
5
+ * Filters and sorts profiled functions based on configuration. Implements smart
6
+ * detection to focus on user code by excluding node_modules and Node.js
7
+ * internals.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.filterProfile = void 0;
13
+ const minimatch_1 = require("minimatch");
14
+ /**
15
+ * Filter profile data based on configuration
16
+ *
17
+ * @param data - Raw profile data
18
+ * @param config - Filter configuration
19
+ * @param packageRoot - Package root directory for smart detection
20
+ * @returns Filtered profile data
21
+ */
22
+ const filterProfile = (data, config, packageRoot) => {
23
+ let filtered = data.functions.filter((fn) => {
24
+ // Only JavaScript functions
25
+ if (fn.category !== 'JavaScript') {
26
+ return false;
27
+ }
28
+ // Apply smart detection if enabled
29
+ if (config.smartDetection && !config.focus?.length) {
30
+ if (!isUserCode(fn.file, packageRoot)) {
31
+ return false;
32
+ }
33
+ }
34
+ // Apply focus patterns (if provided, overrides smart detection)
35
+ if (config.focus?.length) {
36
+ if (!matchesAnyPattern(fn.file, config.focus)) {
37
+ return false;
38
+ }
39
+ }
40
+ // Apply exclude patterns (always applied if provided)
41
+ if (config.exclude?.length) {
42
+ if (matchesAnyPattern(fn.file, config.exclude)) {
43
+ return false;
44
+ }
45
+ }
46
+ return true;
47
+ });
48
+ // Save count of user functions before percentage filtering
49
+ const totalUserFunctions = filtered.length;
50
+ // Apply percentage threshold
51
+ const minPercent = config.minExecutionPercent ?? 0.5;
52
+ filtered = filtered.filter((fn) => fn.percentage >= minPercent);
53
+ // Sort by percentage (highest first)
54
+ filtered.sort((a, b) => b.percentage - a.percentage);
55
+ // Limit to topN
56
+ const topN = config.topN ?? 25;
57
+ filtered = filtered.slice(0, topN);
58
+ // Group by file if requested
59
+ let groupedByFile;
60
+ if (config.groupByFile) {
61
+ groupedByFile = groupByFile(filtered);
62
+ }
63
+ return {
64
+ functions: filtered,
65
+ groupedByFile,
66
+ minExecutionPercent: minPercent,
67
+ summary: data.summary,
68
+ totalFiltered: totalUserFunctions,
69
+ totalShown: filtered.length,
70
+ totalTicks: data.totalTicks,
71
+ };
72
+ };
73
+ exports.filterProfile = filterProfile;
74
+ /**
75
+ * Check if a file path is user code (not node_modules or internals)
76
+ */
77
+ const isUserCode = (filePath, packageRoot) => {
78
+ // Exclude node_modules
79
+ if (filePath.includes('/node_modules/') ||
80
+ filePath.includes('\\node_modules\\')) {
81
+ return false;
82
+ }
83
+ // Exclude Node.js internals
84
+ if (filePath.startsWith('node:') || filePath.startsWith('internal/')) {
85
+ return false;
86
+ }
87
+ // Allow <unknown> files (could be eval'd code or other user code without file paths)
88
+ if (filePath === '<unknown>' || filePath === '[eval]') {
89
+ return true;
90
+ }
91
+ // Must be within package root
92
+ return filePath.startsWith(packageRoot);
93
+ };
94
+ /**
95
+ * Check if a file path matches any of the given glob patterns
96
+ */
97
+ const matchesAnyPattern = (filePath, patterns) => {
98
+ return patterns.some((pattern) => (0, minimatch_1.minimatch)(filePath, pattern));
99
+ };
100
+ /**
101
+ * Group functions by file path
102
+ */
103
+ const groupByFile = (functions) => {
104
+ const grouped = new Map();
105
+ for (const fn of functions) {
106
+ const existing = grouped.get(fn.file) || [];
107
+ existing.push(fn);
108
+ grouped.set(fn.file, existing);
109
+ }
110
+ // Sort functions within each file by percentage
111
+ for (const [, fns] of grouped.entries()) {
112
+ fns.sort((a, b) => b.percentage - a.percentage);
113
+ }
114
+ return grouped;
115
+ };
116
+ //# 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,20 @@
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 type { FilteredProfileData, ProfileConfig, RawProfileData } from "../../types/profiler.cjs";
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 declare const filterProfile: (data: RawProfileData, config: ProfileConfig, packageRoot: string) => FilteredProfileData;
20
+ //# sourceMappingURL=profile-filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-filter.d.ts","sourceRoot":"","sources":["../../../src/services/profiler/profile-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EAEb,cAAc,EACf,iCAAgC;AAEjC;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,cAAc,EACpB,QAAQ,aAAa,EACrB,aAAa,MAAM,KAClB,mBA4DF,CAAC"}
@@ -0,0 +1,20 @@
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 type { FilteredProfileData, ProfileConfig, RawProfileData } from "../../types/profiler.js";
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 declare const filterProfile: (data: RawProfileData, config: ProfileConfig, packageRoot: string) => FilteredProfileData;
20
+ //# sourceMappingURL=profile-filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-filter.d.ts","sourceRoot":"","sources":["../../../src/services/profiler/profile-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EAEb,cAAc,EACf,gCAAgC;AAEjC;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,cAAc,EACpB,QAAQ,aAAa,EACrB,aAAa,MAAM,KAClB,mBA4DF,CAAC"}
@@ -0,0 +1,112 @@
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
+ // Save count of user functions before percentage filtering
46
+ const totalUserFunctions = filtered.length;
47
+ // Apply percentage threshold
48
+ const minPercent = config.minExecutionPercent ?? 0.5;
49
+ filtered = filtered.filter((fn) => fn.percentage >= minPercent);
50
+ // Sort by percentage (highest first)
51
+ filtered.sort((a, b) => b.percentage - a.percentage);
52
+ // Limit to topN
53
+ const topN = config.topN ?? 25;
54
+ filtered = filtered.slice(0, topN);
55
+ // Group by file if requested
56
+ let groupedByFile;
57
+ if (config.groupByFile) {
58
+ groupedByFile = groupByFile(filtered);
59
+ }
60
+ return {
61
+ functions: filtered,
62
+ groupedByFile,
63
+ minExecutionPercent: minPercent,
64
+ summary: data.summary,
65
+ totalFiltered: totalUserFunctions,
66
+ totalShown: filtered.length,
67
+ totalTicks: data.totalTicks,
68
+ };
69
+ };
70
+ /**
71
+ * Check if a file path is user code (not node_modules or internals)
72
+ */
73
+ const isUserCode = (filePath, packageRoot) => {
74
+ // Exclude node_modules
75
+ if (filePath.includes('/node_modules/') ||
76
+ filePath.includes('\\node_modules\\')) {
77
+ return false;
78
+ }
79
+ // Exclude Node.js internals
80
+ if (filePath.startsWith('node:') || filePath.startsWith('internal/')) {
81
+ return false;
82
+ }
83
+ // Allow <unknown> files (could be eval'd code or other user code without file paths)
84
+ if (filePath === '<unknown>' || filePath === '[eval]') {
85
+ return true;
86
+ }
87
+ // Must be within package root
88
+ return filePath.startsWith(packageRoot);
89
+ };
90
+ /**
91
+ * Check if a file path matches any of the given glob patterns
92
+ */
93
+ const matchesAnyPattern = (filePath, patterns) => {
94
+ return patterns.some((pattern) => minimatch(filePath, pattern));
95
+ };
96
+ /**
97
+ * Group functions by file path
98
+ */
99
+ const groupByFile = (functions) => {
100
+ const grouped = new Map();
101
+ for (const fn of functions) {
102
+ const existing = grouped.get(fn.file) || [];
103
+ existing.push(fn);
104
+ grouped.set(fn.file, existing);
105
+ }
106
+ // Sort functions within each file by percentage
107
+ for (const [, fns] of grouped.entries()) {
108
+ fns.sort((a, b) => b.percentage - a.percentage);
109
+ }
110
+ return grouped;
111
+ };
112
+ //# 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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"}