1- import { initCore , measurement , optimizeFunctionSync } from "@codspeed/core" ;
1+ import {
2+ initCore ,
3+ measurement ,
4+ optimizeFunction ,
5+ optimizeFunctionSync ,
6+ } from "@codspeed/core" ;
27import Benchmark from "benchmark" ;
3- import { findUpSync , Options } from "find-up" ;
8+ import { findUpSync , Options as FindupOptions } from "find-up" ;
49import path , { dirname } from "path" ;
510import { get as getStackTrace } from "stack-trace" ;
611
712declare const __VERSION__ : string ;
813
9- export function withCodSpeed ( suite : Benchmark ) : Benchmark ;
10- export function withCodSpeed ( suite : Benchmark . Suite ) : Benchmark . Suite ;
14+ interface WithCodSpeedBenchmark
15+ extends Omit <
16+ Benchmark ,
17+ "run" | "abort" | "clone" | "compare" | "emit" | "off" | "on" | "reset"
18+ > {
19+ abort ( ) : WithCodSpeedBenchmark ;
20+ clone ( options : Benchmark . Options ) : WithCodSpeedBenchmark ;
21+ compare ( benchmark : Benchmark ) : number ;
22+ off (
23+ type ?: string ,
24+ listener ?: CallableFunction
25+ ) : Benchmark | Promise < Benchmark > ;
26+ off ( types : string [ ] ) : WithCodSpeedBenchmark ;
27+ on ( type ?: string , listener ?: CallableFunction ) : WithCodSpeedBenchmark ;
28+ on ( types : string [ ] ) : WithCodSpeedBenchmark ;
29+ reset ( ) : WithCodSpeedBenchmark ;
30+ // Makes run an async function
31+ run ( options ?: Benchmark . Options ) : Benchmark | Promise < Benchmark > ;
32+ }
33+
34+ interface WithCodSpeedSuite
35+ extends Omit <
36+ Benchmark . Suite ,
37+ | "run"
38+ | "abort"
39+ | "clone"
40+ | "compare"
41+ | "emit"
42+ | "off"
43+ | "on"
44+ | "reset"
45+ | "add"
46+ | "filter"
47+ | "each"
48+ | "forEach"
49+ > {
50+ abort ( ) : WithCodSpeedSuite ;
51+ add (
52+ name : string ,
53+ fn : CallableFunction | string ,
54+ options ?: Benchmark . Options
55+ ) : WithCodSpeedSuite ;
56+ add (
57+ fn : CallableFunction | string ,
58+ options ?: Benchmark . Options
59+ ) : WithCodSpeedSuite ;
60+ add ( name : string , options ?: Benchmark . Options ) : WithCodSpeedSuite ;
61+ add ( options : Benchmark . Options ) : WithCodSpeedSuite ;
62+ clone ( options : Benchmark . Options ) : WithCodSpeedSuite ;
63+ filter ( callback : CallableFunction | string ) : WithCodSpeedSuite ;
64+ off ( type ?: string , callback ?: CallableFunction ) : WithCodSpeedSuite ;
65+ off ( types : string [ ] ) : WithCodSpeedSuite ;
66+ on ( type ?: string , callback ?: CallableFunction ) : WithCodSpeedSuite ;
67+ on ( types : string [ ] ) : WithCodSpeedSuite ;
68+ reset ( ) : WithCodSpeedSuite ;
69+ each ( callback : CallableFunction ) : WithCodSpeedSuite ;
70+ forEach ( callback : CallableFunction ) : WithCodSpeedSuite ;
71+
72+ run ( options ?: Benchmark . Options ) : Benchmark . Suite | Promise < Benchmark . Suite > ;
73+ }
74+
75+ export function withCodSpeed ( suite : Benchmark ) : WithCodSpeedBenchmark ;
76+ export function withCodSpeed ( suite : Benchmark . Suite ) : WithCodSpeedSuite ;
1177export function withCodSpeed ( item : unknown ) : unknown {
1278 if ( ( item as { length ?: number } ) . length === undefined ) {
1379 return withCodSpeedBenchmark ( item as Benchmark ) ;
@@ -16,7 +82,7 @@ export function withCodSpeed(item: unknown): unknown {
1682 }
1783}
1884
19- function withCodSpeedBenchmark ( bench : Benchmark ) : Benchmark {
85+ function withCodSpeedBenchmark ( bench : Benchmark ) : WithCodSpeedBenchmark {
2086 if ( ! measurement . isInstrumented ( ) ) {
2187 const rawRun = bench . run ;
2288 bench . run = ( options ?: Benchmark . Options ) => {
@@ -27,27 +93,22 @@ function withCodSpeedBenchmark(bench: Benchmark): Benchmark {
2793 } ;
2894 return bench ;
2995 }
30- initCore ( ) ;
3196 const callingFile = getCallingFile ( ) ;
32- // eslint-disable-next-line @typescript-eslint/no-unused-vars
33- bench . run = function ( options ?: Benchmark . Options ) : Benchmark {
34- console . log (
35- `[CodSpeed] running with @codspeed/benchmark.js v${ __VERSION__ } `
36- ) ;
37- const uri = callingFile + "::" + ( bench . name ?? "unknown" ) ;
38- const fn = bench . fn as CallableFunction ;
39- optimizeFunctionSync ( fn ) ;
40- measurement . startInstrumentation ( ) ;
41- fn ( ) ;
42- measurement . stopInstrumentation ( uri ) ;
43- console . log ( ` ✔ Measured ${ uri } ` ) ;
44- console . log ( "[CodSpeed] Done running 1 bench." ) ;
97+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/ban-ts-comment
98+ // @ts -ignore
99+ bench . run = async function ( options ?: Benchmark . Options ) : Promise < Benchmark > {
100+ await runBenchmarks ( {
101+ benches : [ bench as unknown as BenchmarkWithOptions ] ,
102+ baseUri : callingFile ,
103+ benchmarkCompletedListeners : bench . listeners ( "complete" ) ,
104+ options,
105+ } ) ;
45106 return bench ;
46107 } ;
47108 return bench ;
48109}
49110
50- function withCodSpeedSuite ( suite : Benchmark . Suite ) : Benchmark . Suite {
111+ function withCodSpeedSuite ( suite : Benchmark . Suite ) : WithCodSpeedSuite {
51112 if ( ! measurement . isInstrumented ( ) ) {
52113 const rawRun = suite . run ;
53114 suite . run = ( options ?: Benchmark . Options ) => {
@@ -56,35 +117,82 @@ function withCodSpeedSuite(suite: Benchmark.Suite): Benchmark.Suite {
56117 ) ;
57118 return rawRun . bind ( suite ) ( options ) ;
58119 } ;
59- return suite ;
120+ return suite as WithCodSpeedSuite ;
60121 }
61- initCore ( ) ;
62122 const callingFile = getCallingFile ( ) ;
63- // eslint-disable-next-line @typescript-eslint/no-unused-vars
64- suite . run = function ( options ?: Benchmark . Options ) : Benchmark . Suite {
65- console . log (
66- `[CodSpeed] running with @codspeed/benchmark.js v ${ __VERSION__ } `
67- ) ;
123+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/ban-ts-comment
124+ // @ts -ignore
125+ suite . run = async function (
126+ options ?: Benchmark . Options
127+ ) : Promise < Benchmark . Suite > {
68128 const suiteName = suite . name ;
69- const benches = this as unknown as Benchmark [ ] ;
129+ const benches = this as unknown as BenchmarkWithOptions [ ] ;
70130 let baseUri = callingFile ;
71131 if ( suiteName !== undefined ) {
72132 baseUri += `::${ suiteName } ` ;
73133 }
74- for ( let i = 0 ; i < benches . length ; i ++ ) {
75- const bench = benches [ i ] ;
76- const uri = baseUri + "::" + ( bench . name ?? `unknown_${ i } ` ) ;
77- const fn = bench . fn as CallableFunction ;
78- optimizeFunctionSync ( fn ) ;
134+ await runBenchmarks ( {
135+ benches,
136+ baseUri,
137+ benchmarkCompletedListeners : suite . listeners ( "complete" ) ,
138+ options,
139+ } ) ;
140+ return suite ;
141+ } ;
142+ return suite as WithCodSpeedSuite ;
143+ }
144+
145+ type BenchmarkWithOptions = Benchmark & { options : Benchmark . Options } ;
146+
147+ interface RunBenchmarksOptions {
148+ benches : BenchmarkWithOptions [ ] ;
149+ baseUri : string ;
150+ benchmarkCompletedListeners : CallableFunction [ ] ;
151+ options ?: Benchmark . Options ;
152+ }
153+
154+ async function runBenchmarks ( {
155+ benches,
156+ baseUri,
157+ benchmarkCompletedListeners,
158+ options,
159+ } : RunBenchmarksOptions ) : Promise < void > {
160+ console . log ( `[CodSpeed] running with @codspeed/benchmark.js v${ __VERSION__ } ` ) ;
161+ initCore ( ) ;
162+ for ( let i = 0 ; i < benches . length ; i ++ ) {
163+ const bench = benches [ i ] ;
164+ const uri = baseUri + "::" + ( bench . name ?? `unknown_${ i } ` ) ;
165+ const isAsync =
166+ bench . options . async || bench . options . defer || options ?. async ;
167+ let benchPayload ;
168+ if ( bench . options . defer ) {
169+ benchPayload = ( ) => {
170+ return new Promise ( ( resolve , reject ) => {
171+ ( bench . fn as CallableFunction ) ( { resolve, reject } ) ;
172+ } ) ;
173+ } ;
174+ } else if ( bench . options . async ) {
175+ benchPayload = async ( ) => {
176+ await ( bench . fn as CallableFunction ) ( ) ;
177+ } ;
178+ } else {
179+ benchPayload = bench . fn as CallableFunction ;
180+ }
181+ if ( isAsync ) {
182+ await optimizeFunction ( benchPayload ) ;
79183 measurement . startInstrumentation ( ) ;
80- ( bench . fn as CallableFunction ) ( ) ;
184+ await benchPayload ( ) ;
185+ measurement . stopInstrumentation ( uri ) ;
186+ } else {
187+ optimizeFunctionSync ( benchPayload ) ;
188+ measurement . startInstrumentation ( ) ;
189+ benchPayload ( ) ;
81190 measurement . stopInstrumentation ( uri ) ;
82- console . log ( ` ✔ Measured ${ uri } ` ) ;
83191 }
84- console . log ( `[CodSpeed] Done running ${ suite . length } benches. ` ) ;
85- return suite ;
86- } ;
87- return suite ;
192+ console . log ( ` ✔ Measured ${ uri } ` ) ;
193+ benchmarkCompletedListeners . forEach ( ( listener ) => listener ( ) ) ;
194+ }
195+ console . log ( `[CodSpeed] Done running ${ benches . length } benches.` ) ;
88196}
89197
90198function getCallingFile ( ) : string {
@@ -101,6 +209,6 @@ function getGitDir(path: string): string | undefined {
101209 const dotGitPath = findUpSync ( ".git" , {
102210 cwd : path ,
103211 type : "directory" ,
104- } as Options ) ;
212+ } as FindupOptions ) ;
105213 return dotGitPath ? dirname ( dotGitPath ) : undefined ;
106214}
0 commit comments