ostia 0.2.0 → 0.2.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.
package/README.md CHANGED
@@ -151,6 +151,41 @@ or last. `--no-interleave` (`interleave: false`) goes back to running each comma
151
151
  loop to completion in turn. Interleaved measurements carry `Measurement.interleaved: true`.
152
152
  Meaningless (and ignored) with a single command.
153
153
 
154
+ `--prepare CMD` runs `CMD` before *every* trial (warmup and `--cpu`/`--heap` trials
155
+ included), unmeasured, in the same cwd - hyperfine's `--prepare`. It's whitespace-split
156
+ like the commands themselves (no shell) and must exit 0. Given once it applies to every
157
+ command; given once per command it pairs up in order, which is how the same command gets
158
+ timed warm and cold side by side:
159
+
160
+ ```sh
161
+ ostia time --prepare "true" --prepare "rm -rf dist" "bun build.ts" "bun build.ts"
162
+ ```
163
+
164
+ The prepare command is part of the workload id (and lands on the document as
165
+ `Workload.prepare`), so a command with and without one are two workloads, and `ostia ci`
166
+ caches them separately. The library API also takes a function
167
+ (`prepare: ({ phase, index }) => ...`, see [`time(opts)`](#timeopts--profiledocument)).
168
+
169
+ `--time-source REGEX` takes each trial's time from the command's *own output* instead of
170
+ its wall clock: the first `REGEX` match in stdout (then stderr), capture group 1, in
171
+ `--time-unit` units (`ns` | `us` | `ms` | `s`, default `ms`). Meant for tools that report a
172
+ more precise cost than wall time - a build tool whose `built in 342ms` line excludes the
173
+ runtime's startup - so a Bun startup regression isn't misattributed to the tool, and vice
174
+ versa:
175
+
176
+ ```sh
177
+ ostia time --time-source "built in (\d+)ms" "bun build.ts"
178
+ ```
179
+
180
+ The parsed value becomes `timing.samples`, so `compare`/`ci`/every renderer treat it
181
+ exactly like wall time; each trial keeps `wallNs` alongside `reportedNs` so the document
182
+ has both. A trial whose output doesn't match aborts the run with the output quoted (the
183
+ workload asked for a number that isn't there). To gate wall time *and* the reported time
184
+ independently, declare the command twice - once plain, once with `--time-source` - and
185
+ they're two workloads with two verdicts. Note the reported number has whatever resolution
186
+ the tool printed (usually whole ms), so its confidence interval is coarser than a
187
+ nanosecond wall clock's.
188
+
154
189
  Timing table (two commands get a Relative column automatically):
155
190
 
156
191
  ```
@@ -313,6 +348,13 @@ Warnings:
313
348
  Tasks with a `group()` print the group name once, indented; ungrouped tasks and
314
349
  subprocess commands print flat.
315
350
 
351
+ There's no built-in watch mode. For an edit/re-run loop while writing a suite, pair
352
+ `ostia bench` with a file watcher and a small budget:
353
+
354
+ ```sh
355
+ watchexec -e ts -- ostia bench bench/parse.ts --budget 100
356
+ ```
357
+
316
358
  ### `ostia compare`
317
359
 
318
360
  Match workloads by id, rank timing / frame / heap deltas, print a verdict per workload.
@@ -503,6 +545,13 @@ export default defineConfig({
503
545
  workloads: [
504
546
  { label: "parse", command: ["bun", "bench/parse.ts"], inputs: ["src/**/*.ts"] },
505
547
  { label: "dogfood-suites", suites: ["bench/*.ts"] },
548
+ // Same command, three states: warm no-op, one edited input, cold. `prepare`
549
+ // runs before every trial; `timeSource` reads the tool's own "in Nms" line.
550
+ { label: "build:warm", command: ["bun", "cli.ts", "build", "fixture"], timeSource: { pattern: "in (\\d+)ms" } },
551
+ { label: "build:incremental", command: ["bun", "cli.ts", "build", "fixture"], timeSource: { pattern: "in (\\d+)ms" },
552
+ prepare: () => touchPost("fixture/posts/hello.md") },
553
+ { label: "build:cold", command: ["bun", "cli.ts", "build", "fixture"], timeSource: { pattern: "in (\\d+)ms" },
554
+ prepare: "rm -rf fixture/dist" },
506
555
  ],
507
556
  })
508
557
  ```
@@ -538,6 +587,13 @@ keys, without importing it first) - `inputs`-based cache skipping is `command`-o
538
587
  `inputs` is optional (and, for now, only consulted for `command` workloads). Workloads
539
588
  with no `inputs` always rerun (cache fails conservative).
540
589
 
590
+ `prepare` and `timeSource` are `command`-only and mean the same as `ostia time`'s
591
+ `--prepare` / `--time-source`: `prepare` is a command string or argv array in both config
592
+ forms, or a function in `ostia.config.ts`; `timeSource` is `{ pattern, group?, unit? }`
593
+ with `pattern` a regex source string (or a `RegExp` in `.ts`). Both are part of the workload
594
+ id. A function-form `prepare` can't be fingerprinted, so that workload never comes from
595
+ cache - it always executes, like a workload with no `inputs`.
596
+
541
597
  Two directory options, both optional: `outDir` (default `node_modules/.cache/ostia`) for
542
598
  scratch/cache/artifacts, and `baselineDir` (default `.ostia/baselines`) for baselines. They're
543
599
  independent - `baselineDir` doesn't move just because you override `outDir`.
@@ -621,6 +677,9 @@ Subprocess timing, optional CPU/heap capture. Same behavior as `ostia time`.
621
677
  ```ts
622
678
  const doc = await time({
623
679
  commands: ["bun a.ts", "bun b.ts"],
680
+ prepare: "rm -rf dist", // before every trial of every command, unmeasured; or a
681
+ // function: ({ phase, index }) => ..., phase is "warmup" | "timing" | "cpu" | "heap"
682
+ timeSource: { pattern: /in (\d+)ms/, unit: "ms" }, // samples from the command's own output
624
683
  samples: 10, // exact trial count
625
684
  // budgetMs: 3000, // wall-clock budget instead of an exact count
626
685
  // minSamples: 10, // hard floor when samples isn't given
@@ -634,6 +693,24 @@ const doc = await time({
634
693
  })
635
694
  ```
636
695
 
696
+ A command can also be an object - `{ command, label?, prepare?, timeSource? }` - whose
697
+ `prepare`/`timeSource` override the top-level ones for that command. That's how one
698
+ command becomes several labeled workloads in the same document:
699
+
700
+ ```ts
701
+ const build = ["bun", "cli.ts", "build", "fixture"]
702
+ const inMs = { pattern: /in (\d+)ms/ }
703
+ const doc = await time({
704
+ commands: [
705
+ { command: build, label: "warm", timeSource: inMs },
706
+ { command: build, label: "incremental", timeSource: inMs, prepare: () => touchPost() },
707
+ { command: build, label: "cold", timeSource: inMs, prepare: "rm -rf fixture/dist" },
708
+ { command: build, label: "wall clock" }, // same command, no timeSource: wall time
709
+ ],
710
+ samples: 5,
711
+ })
712
+ ```
713
+
637
714
  ### `profile(fn, opts)` → `{ result, measurement, document }`
638
715
 
639
716
  In-process capture. `origin: "jsc"` is the only path that reports JIT tiers
@@ -862,6 +939,24 @@ const doc = await bench({
862
939
  })
863
940
  ```
864
941
 
942
+ A command can also be an object - `{ command, label?, prepare?, timeSource? }` - whose
943
+ `prepare`/`timeSource` override the top-level ones for that command. That's how one
944
+ command becomes several labeled workloads in the same document:
945
+
946
+ ```ts
947
+ const build = ["bun", "cli.ts", "build", "fixture"]
948
+ const inMs = { pattern: /in (\d+)ms/ }
949
+ const doc = await time({
950
+ commands: [
951
+ { command: build, label: "warm", timeSource: inMs },
952
+ { command: build, label: "incremental", timeSource: inMs, prepare: () => touchPost() },
953
+ { command: build, label: "cold", timeSource: inMs, prepare: "rm -rf fixture/dist" },
954
+ { command: build, label: "wall clock" }, // same command, no timeSource: wall time
955
+ ],
956
+ samples: 5,
957
+ })
958
+ ```
959
+
865
960
  ### `compareDocuments(base, cand, thresholds?)` → `Comparison[]`
866
961
 
867
962
  Same matching and thresholds as `ostia compare` / `ostia ci`.
@@ -925,6 +1020,7 @@ Units in the IR are fixed: ns (time), bytes (memory), µs (sampling interval).
925
1020
  | `do_not_optimize(value)` | `keep(value)` |
926
1021
  | `hyperfine -L var a,b,c cmd-{var}` | `sweep({ var: ["a", "b", "c"] }, ...)` or per-command `params` |
927
1022
  | `hyperfine --runs N --warmup N` | `ostia time --samples N --warmup N` |
1023
+ | `hyperfine --prepare CMD` | `ostia time --prepare CMD` (also `time({ prepare })` / config `prepare`) |
928
1024
  | `hyperfine --export-json` / `--export-markdown` | `ostia time --export-json PATH` / `--format markdown` |
929
1025
 
930
1026
  `sweep()`/`range()`/`params` are in-process (`ostia bench`); `hyperfine -L` substitutes into
@@ -0,0 +1,8 @@
1
+ // @bun
2
+ var De={ns:1,us:1000,ms:1e6,s:1e9};async function D(r){let c=r.timeSource!==void 0,l=Bun.nanoseconds(),b=Bun.spawn(r.argv,{cwd:r.cwd,env:r.env,stdout:c?"pipe":"ignore",stderr:c?"pipe":"ignore",stdin:"ignore"}),R=c?Promise.all([new Response(b.stdout).text(),new Response(b.stderr).text()]):void 0,M=await b.exited,N=Bun.nanoseconds(),C=b.resourceUsage?.(),G={wallNs:N-l,exitCode:M,userNs:C?Number(C.cpuTime.user)*1000:void 0,systemNs:C?Number(C.cpuTime.system)*1000:void 0,maxRssBytes:C?.maxRSS};if(R&&r.timeSource){let[V,ee]=await R;G.reportedNs=_e(r.timeSource,V,ee,r.argv)}return G}function _e(r,c,l,b=[]){let R=typeof r.pattern==="string"?new RegExp(r.pattern):r.pattern,M=r.group??1,N=R.exec(c)??R.exec(l),C=b.length>0?` for "${b.join(" ")}"`:"";if(!N)throw Error(`timeSource pattern ${R} did not match the output${C}. Output was:
3
+ ${$e(c,l)}`);let G=N[M];if(G===void 0)throw Error(`timeSource pattern ${R} matched${C} but has no capture group ${M} (matched text: "${N[0]}").`);let V=Number(G);if(!Number.isFinite(V))throw Error(`timeSource pattern ${R} group ${M} captured "${G}"${C}, which is not a number.`);return V*De[r.unit??"ms"]}function $e(r,c){let b=(M)=>M.length>800?`${M.slice(0,800)}\u2026(${M.length-800} more)`:M,R=[];if(r.trim())R.push(`--- stdout ---
4
+ ${b(r.trimEnd())}`);if(c.trim())R.push(`--- stderr ---
5
+ ${b(c.trimEnd())}`);return R.length>0?R.join(`
6
+ `):"(empty)"}async function k(r,c,l){if(typeof r==="function"){await r(c);return}let b=Array.isArray(r)?r:y(r),M=await Bun.spawn(b,{cwd:l.cwd,env:l.env,stdout:"ignore",stderr:"inherit",stdin:"ignore"}).exited;if(M!==0)throw Error(`prepare command "${b.join(" ")}" exited with code ${M} before ${c.phase} trial ${c.index}.`)}function Re(r){if(r===void 0||typeof r==="function")return;return Array.isArray(r)?r:y(r)}function Me(r){if(r===void 0)return;return{pattern:typeof r.pattern==="string"?r.pattern:r.pattern.source,...r.group!==void 0&&{group:r.group},...r.unit!==void 0&&{unit:r.unit}}}function y(r){return r.trim().split(/\s+/).filter(Boolean)}function x(r){return JSON.stringify(ge(r))}function ge(r){if(Array.isArray(r))return r.map(ge);if(r!==null&&typeof r==="object"){let c={};for(let l of Object.keys(r).sort())c[l]=ge(r[l]);return c}return r}function e(r,...c){let l=Bun.CryptoHasher.hash("sha256",x(c),"hex");return`${r}_${l.slice(0,16)}`}var be,Se=!1;function ke(r){let c=Bun.spawnSync(["git",...r],{timeout:200,stdout:"pipe",stderr:"ignore"});return c.success?c.stdout.toString().trim():void 0}function ve(){if(Se)return be;Se=!0;try{let r=ke(["rev-parse","--short","HEAD"]);if(r===void 0)be=void 0;else{let c=ke(["rev-parse","--abbrev-ref","HEAD"]),l=ke(["status","--porcelain"]);be={sha:r,branch:c??"HEAD",dirty:(l?.length??0)>0}}}catch{be=void 0}return be}var m="0.1.0";function n(r,c,l){let b=ve();return{schemaVersion:2,toolVersion:m,bunVersion:Bun.version,platform:{os:process.platform,arch:process.arch},createdAt:new Date().toISOString(),workloads:r,measurements:c,...l!==void 0&&{environment:l},...b!==void 0&&{git:b}}}function p(r,c,l={}){let b=Re(l.prepare),R=Me(l.timeSource),M=typeof l.prepare==="function"?l.prepare.toString():b;return{id:e("wl","subprocess",r,process.cwd(),...M!==void 0||R!==void 0?[M??null,R??null]:[]),kind:"subprocess",command:r,label:c,...b!==void 0&&{prepare:b},...R!==void 0&&{timeSource:R}}}function F(r,c){return{id:e("wl","inprocess",r.name,r.toString()),kind:"inprocess",label:c}}function O(r,c,l={}){return{id:l.params!==void 0?e("wl","inprocess-entry",r,c,l.params):e("wl","inprocess-entry",r,c),kind:"inprocess",entry:{file:r,task:c,...l.group!==void 0&&{group:l.group}},...l.label!==void 0&&{label:l.label},...l.baseline!==void 0&&{baseline:l.baseline},...l.description!==void 0&&{description:l.description},...l.groupDescription!==void 0&&{groupDescription:l.groupDescription},...l.isolated!==void 0&&{isolated:l.isolated},...l.params!==void 0&&{params:l.params},...l.skipped!==void 0&&{skipped:l.skipped}}}function i(r){return{id:e("run",r.workload.id,"timing",r.configFingerprint,Bun.version,m),workloadId:r.workload.id,phase:"timing",instrumented:!1,configFingerprint:r.configFingerprint,trials:r.trials,timing:r.timing,warnings:r.warnings,artifacts:[],memory:Ce(r.trials),...r.interleaved!==void 0&&{interleaved:r.interleaved}}}function Ce(r){let c=r.map((l)=>l.maxRssBytes).filter((l)=>l!==void 0);if(c.length===0)return;return{origin:"resourceUsage",perTrial:r.map((l)=>({rssBytes:l.maxRssBytes})),maxRssBytes:Math.max(...c)}}function a(r){return{id:e("run",r.workload.id,r.phase,r.configFingerprint,Bun.version,m),workloadId:r.workload.id,phase:r.phase,instrumented:!0,configFingerprint:r.configFingerprint,trials:[{i:0,wallNs:r.diagnosticWallNs,exitCode:r.exitCode}],diagnosticWallNs:r.diagnosticWallNs,cpu:r.cpu,heap:r.heap,memory:r.memory,jit:r.jit,warnings:r.warnings,artifacts:r.artifacts}}async function E(r,c,l){let R=await Bun.file(l).arrayBuffer(),M=new Bun.CryptoHasher("sha256");return M.update(R),{id:e("art",r,c,l),kind:c,path:l,sha256:M.digest("hex"),bytes:R.byteLength}}function o(r){return e("cfg",r)}function S(r){return`${JSON.stringify(ge(r),null,2)}
7
+ `}async function s(r,c){await Bun.write(c,S(r))}function We(r){if(r.schemaVersion===2)return r;let{runs:c,comparisons:l,...b}=r;return{...b,schemaVersion:2,measurements:c.map(({baselineRunId:R,...M})=>({...M,...R!==void 0&&{baselineMeasurementId:R}})),...l!==void 0&&{comparisons:l.map(({baselineRunId:R,candidateRunId:M,...N})=>({...N,baselineMeasurementId:R,candidateMeasurementId:M}))}}}async function t(r){let c=await Bun.file(r).text(),l=JSON.parse(c);return We(l)}import{profile as Le}from"bun:jsc";var Ge=new Map([["LLInt","llint"],["Baseline","baseline"],["DFG","dfg"],["FTL","ftl"]]),Ie=4294967295;function Ne(r,c){let l=c??r.interval*1e6,b=new Map,R=[];function M(w,v,J,ne){let re=b.get(w);if(re===void 0)re=new Map,b.set(w,re);let Y=v??"",se=re.get(Y);if(se===void 0)se=R.length,re.set(Y,se),R.push({key:e("fr",w,Y),name:w,url:v,line:J,col:ne});return se}function N(w){let v=w.line===Ie,J=v?void 0:w.line-1,ne=v||w.column===Ie?void 0:w.column-1;return M(w.name,w.sourceURL,J,ne)}let C=M("(root)",void 0,void 0,void 0),G=1,V={id:0,frameIx:C,children:new Map,selfUs:0,samples:0,totalUs:0},ee=new Map([[0,V]]),te={llint:0,baseline:0,dfg:0,ftl:0},X=new Map,me=[],ae=[];for(let w of r.traces){let v=w.frames,J=V;for(let Y=v.length-1;Y>=0;Y--){let se=N(v[Y]),pe=J.children.get(se);if(!pe)pe={id:G++,frameIx:se,children:new Map,selfUs:0,samples:0,totalUs:0},J.children.set(se,pe),ee.set(pe.id,pe);J=pe}J.selfUs+=l,J.samples+=1,me.push(J.id),ae.push(l);let ne=v[0],re=ne&&Ge.get(ne.category);if(re){te[re]++;let Y=X.get(re)??new Map;Y.set(J.frameIx,(Y.get(J.frameIx)??0)+1),X.set(re,Y)}}function oe(w){let v=w.selfUs;for(let J of w.children.values())v+=oe(J);return w.totalUs=v,v}oe(V);let ue=new Map;function ie(w){let v=ue.get(w.frameIx);if(v)v.selfUs+=w.selfUs,v.totalUs+=w.totalUs,v.samples+=w.samples;else ue.set(w.frameIx,{frameIx:w.frameIx,selfUs:w.selfUs,totalUs:w.totalUs,samples:w.samples});for(let J of w.children.values())ie(J)}ie(V);let ce=[...ee.values()].map((w)=>({id:w.id,frameIx:w.frameIx,children:[...w.children.values()].map((v)=>v.id)})),le={origin:"jsc-profile",samplingIntervalUs:l,frames:R,nodes:ce,totals:[...ue.values()].sort((w,v)=>v.selfUs-w.selfUs),samples:{nodeIds:me,timeDeltasUs:ae}},z=[...X.entries()].flatMap(([w,v])=>[...v.entries()].sort((J,ne)=>ne[1]-J[1]).slice(0,3).map(([J,ne])=>({tier:w,frameKey:R[J].key,samples:ne})));return{cpu:le,jit:{origin:"jsc-profile",tiers:te,topFramesByTier:z}}}var He=1000;async function d(r,c={}){let l=c.intervalUs??He,b,R=Bun.nanoseconds(),M=await Le(async()=>(b=await r(),b),l),N=Bun.nanoseconds()-R,{cpu:C,jit:G}=Ne(M.stackTraces,l);return{result:b,cpu:C,jit:G,diagnosticWallNs:N}}import Te from"os";function u(r){if(r.length===0)throw Error("computeTimingStats: samples must be non-empty");let c=r.length,l=Ee(r),b=0;for(let w=0;w<c;w++)b+=r[w];let R=b/c,M=de(l,0.5),N=0;for(let w=0;w<c;w++){let v=r[w]-R;N+=v*v}let C=Math.sqrt(N/c),G=l[0],V=l[c-1],ee=de(l,0.25),te=de(l,0.75),X=te-ee,me=ee-1.5*X,ae=te+1.5*X,oe=ee-3*X,ue=te+3*X,ie=0,ce=0;for(let w=0;w<c;w++){let v=r[w];if(v<oe||v>ue)ce++;else if(v<me||v>ae)ie++}let le=de(l,0.99),z=new Float64Array(c);for(let w=0;w<c;w++)z[w]=Math.abs(r[w]-M);z.sort();let Q=de(z,0.5);return{unit:"ns",samples:r,mean:R,median:M,stddev:C,min:G,max:V,outliers:{mild:ie,severe:ce},p75:te,p99:le,mad:Q}}function Ee(r){let c=new Float64Array(r.length);return c.set(r),c.sort(),c}function de(r,c){let l=r.length;if(l===1)return r[0];let b=c*(l-1),R=Math.floor(b),M=Math.ceil(b);if(R===M)return r[R];let N=b-R;return r[R]*(1-N)+r[M]*N}var Je=5000000,je=200;function P(r,c,l="subprocess"){let b=[],R=r.samples[0];if(R!==void 0){let N=Ee(r.samples),C=de(N,0.25),V=de(N,0.75)-C;if(R>r.median+3*V&&V>0)b.push({code:"slow-first-run",message:`First run took ${(R/1e6).toFixed(2)}ms, much slower than the median ${(r.median/1e6).toFixed(2)}ms. Consider more warmup.`,data:{firstNs:R,medianNs:r.median}})}if(r.outliers.mild+r.outliers.severe>0)b.push({code:"outliers-detected",message:`${r.outliers.mild+r.outliers.severe} outlier(s) detected (${r.outliers.severe} severe, ${r.outliers.mild} mild).`,data:r.outliers});if(l==="subprocess"&&r.median<Je)b.push({code:"fast-command",message:`Median run time (${(r.median/1e6).toFixed(3)}ms) is very fast; results may be dominated by spawn overhead.`,data:{medianNs:r.median}});if(l==="inprocess"&&r.median<je)b.push({code:"below-timer-resolution",message:`Median run time (${r.median.toFixed(0)}ns) is close to timer resolution; consider a larger batch size or a coarser operation.`,data:{medianNs:r.median}});let M=c.filter((N)=>N!==void 0&&N!==0);if(M.length>0)b.push({code:"nonzero-exit",message:`${M.length} of ${c.length} trial(s) exited non-zero.`,data:{exitCodes:M}});return b}var Ve=200,Fe=64,qe=(()=>{let r=new Uint8Array(4096);for(let c=0;c<r.length;c++)r[c]=c*2654435761&255;return r})();function ze(r,c){let l=c;for(let b=0;b<r.length;b++)l^=r[b],l=Math.imul(l,16777619);return l>>>0}function Ke(r){let c=u(r),l=c.mad??0;return{floorPct:c.median===0?0:l/c.median*100,referenceMedianNs:c.median,samples:r.length}}function Be(r=Ve){let c=r*1e6,l=[],b=0,R=Bun.nanoseconds(),M=0;while(M<c){let N=Bun.nanoseconds();for(let G=0;G<Fe;G++)b^=ze(qe,G);let C=Bun.nanoseconds();l.push((C-N)/Fe),M=Bun.nanoseconds()-R}return Ke(l)}var Xe=0.75;function f(){let[r=0,c=0]=Te.loadavg();return{cpuModel:Te.cpus()[0]?.model??"unknown",cores:Te.availableParallelism(),loadAvg1:r,loadAvg5:c,noise:Be()}}function g(r){if(r.loadAvg1<=r.cores*Xe)return;return{code:"noisy-machine",message:`Load average ${r.loadAvg1.toFixed(2)} exceeds 75% of ${r.cores} available core(s); timing noise may be elevated.`,data:{loadAvg1:r.loadAvg1,cores:r.cores}}}var Ze=500,Qe=20,Oe=3,Ye=10,en=2,nn=0.1,rn=1000,tn=1e4;function Ue(r){let c=Math.log10(Math.max(1,r)/1e6),l=Math.round(Oe+en*c);return Math.min(Ye,Math.max(Oe,l))}function on(r,c){let l=Math.floor(c/r);return Math.min(Qe,Math.max(l,Ue(r)))}var Pe=0;function T(r){if(typeof r==="number")Pe+=r;else if(r!==void 0&&r!==null)Pe+=1}function we(r){return r!==null&&typeof r==="object"&&typeof r.then==="function"}function Ae(r,c){return Math.max(1,Math.ceil(rn/r),Math.ceil(c/(r*tn)))}async function U(r,c={}){let l=(c.budgetMs??Ze)*1e6,b=l*(c.warmup??nn),R=Bun.nanoseconds(),M=0,N=0;while(N<b){let z=r();T(we(z)?await z:z),M++,N=Bun.nanoseconds()-R}let C;if(M>0)C=Math.max(1,N/M);else{let z=Bun.nanoseconds(),Q=r();T(we(Q)?await Q:Q),C=Math.max(1,Bun.nanoseconds()-z)}let G=Ae(C,l);if(G>1){let z=Bun.nanoseconds();for(let Q=0;Q<G;Q++){let w=r();T(we(w)?await w:w)}C=Math.max(1,(Bun.nanoseconds()-z)/G),G=Ae(C,l)}let V=C*G,ee=c.samples??c.minSamples??on(V,l),te=c.samples!==void 0?0:l,X=[],me=Bun.nanoseconds(),ae=0,oe=0;while(oe<ee||ae<te){let z=Bun.nanoseconds();for(let w=0;w<G;w++){let v=r();T(we(v)?await v:v)}let Q=Bun.nanoseconds();if(X.push({i:oe,wallNs:(Q-z)/G}),oe++,ae=Bun.nanoseconds()-me,c.gc)Bun.gc(!0);if(c.samples!==void 0&&oe>=c.samples)break}let ue=X.map((z)=>z.wallNs),ie=u(ue),ce=P(ie,[],"inprocess"),le=Ue(V);if(X.length<le)ce.push({code:"low-sample-count",message:`Only ${X.length} sample(s) at ~${sn(V)} per trial; ${le} is the floor for this cost class. Raise minSamples or the time budget for a steadier number.`,data:{samples:X.length,target:le,trialCostNs:V}});return{trials:X,timing:ie,warnings:ce}}function sn(r){if(r>=1e9)return`${(r/1e9).toFixed(2)}s`;if(r>=1e6)return`${(r/1e6).toFixed(1)}ms`;if(r>=1000)return`${(r/1000).toFixed(1)}\xB5s`;return`${r.toFixed(0)}ns`}var ye=[],Z,fe;function xe(r,c,l,b){let R=Z;Z={name:r,description:l?.description,isolate:l?.isolate,gc:l?.gc,cpu:l?.cpu,alloc:l?.alloc,before:l?.before,after:l?.after,skip:b.skip,only:b.only};try{c()}finally{Z=R}}var q=Object.assign((r,c,l)=>xe(r,c,l,{}),{skip:(r,c,l)=>xe(r,c,l,{skip:!0}),only:(r,c,l)=>xe(r,c,l,{only:!0})});function he(r,c,l,b){let R=fe!==void 0||l?.params!==void 0?{...fe,...l?.params}:void 0;ye.push({groupName:Z?.name,groupDescription:Z?.description,groupIsolate:Z?.isolate,groupGc:Z?.gc,groupCpu:Z?.cpu,groupAlloc:Z?.alloc,groupBefore:Z?.before,groupAfter:Z?.after,name:r,fn:c,baseline:l?.baseline,params:R,skipped:b.skip||Z?.skip,only:b.only||Z?.only,opts:l})}var K=Object.assign((r,c,l)=>he(r,c,l,{}),{skip:(r,c,l)=>he(r,c,l,{skip:!0}),only:(r,c,l)=>he(r,c,l,{only:!0})});function B(){return ye}function A(){ye.length=0,Z=void 0,fe=void 0}function W(r,c){let l=fe;fe=r;try{return c()}finally{fe=l}}function h(r){return r.groupName?`${r.groupName}/${r.name}`:r.name}function I(r,c){return r.opts?.isolate??r.groupIsolate??c}function j(r,c){return r.opts?.gc??r.groupGc??c}function _(r,c){return r.opts?.cpu??r.groupCpu??c}function L(r,c){return r.opts?.alloc??r.groupAlloc??c}function H(r,c){if(!c)return[...r];let l=new RegExp(c);return r.filter((b)=>l.test(h(b)))}
8
+ export{D,k,y,x,e,m,n,p,F,O,i,a,E,o,S,s,t,u,P,d,f,g,T,U,q,K,B,A,W,h,I,j,_,L,H};
@@ -0,0 +1,21 @@
1
+ // @bun
2
+ import{D,k,y,x,e,n,p,F,i,a,E,o,S,t,u,P,d,f,g,W}from"./chunk-9dqf5cxf.js";function wn(s){return s.startsWith("file://")?s.slice(7):s}function ke(s,h,m){let T=s.nodes,U=T.length,B=new Map,I=[],A=new Map,_=new Int32Array(U);for(let q=0;q<U;q++){let Q=T[q],Z=Q.callFrame,ie=wn(Z.url),se=B.get(Z.functionName);if(se===void 0)se=new Map,B.set(Z.functionName,se);let ce=se.get(ie);if(ce===void 0)ce=I.length,se.set(ie,ce),I.push({key:e("fr",Z.functionName,ie),name:Z.functionName,url:ie||void 0,line:Z.lineNumber>=0?Z.lineNumber:void 0,col:Z.columnNumber>=0?Z.columnNumber:void 0});_[q]=ce,A.set(Q.id,q)}let O=Array(U);for(let q=0;q<U;q++){let Q=T[q];O[q]={id:Q.id,frameIx:_[A.get(Q.id)],children:Q.children??[]}}let j=new Float64Array(U),Y=new Float64Array(U),{samples:L,timeDeltas:K}=s;for(let q=0;q<L.length;q++){let Q=A.get(L[q]);if(Q===void 0)continue;j[Q]+=K[q]??0,Y[Q]+=1}let X=new Int32Array(U).fill(-1);for(let q=0;q<U;q++){let Q=T[q].children;if(!Q)continue;for(let Z of Q){let ie=A.get(Z);if(ie!==void 0)X[ie]=q}}let H=[],te=[];for(let q=U-1;q>=0;q--)if(X[q]===-1)te.push(q);while(te.length>0){let q=te.pop();H.push(q);let Q=T[q].children;if(!Q)continue;for(let Z of Q){let ie=A.get(Z);if(ie!==void 0&&X[ie]===q)te.push(ie)}}let re=new Float64Array(U);for(let q=H.length-1;q>=0;q--){let Q=H[q];re[Q]+=j[Q];let Z=X[Q];if(Z>=0)re[Z]+=re[Q]}let oe=Array(I.length),ne=[];for(let q=0;q<U;q++){let Q=O[q].frameIx,Z=oe[Q];if(Z)Z.selfUs+=j[q],Z.totalUs+=re[q],Z.samples+=Y[q];else{let ie={frameIx:Q,selfUs:j[q],totalUs:re[q],samples:Y[q]};oe[Q]=ie,ne.push(ie)}}return{origin:h,samplingIntervalUs:m,frames:I,nodes:O,totals:ne.sort((q,Q)=>Q.selfUs-q.selfUs),samples:{nodeIds:s.samples,timeDeltasUs:s.timeDeltas}}}function xn(s,h,m,T){let U=["--cpu-prof","--cpu-prof-dir",h,"--cpu-prof-name",m,"--cpu-prof-interval",String(T)],B=s[0];if(B==="bun"||B?.endsWith("/bun"))return[B,...U,...s.slice(1)];return s}async function Fe(s){let h=`${s.artifactDir}/${s.fileName}`,m=s.argv[0],T=m==="bun"||m?.endsWith("/bun"),U=xn(s.argv,s.artifactDir,s.fileName,s.intervalUs),B=T?s.env:{...process.env,...s.env,BUN_OPTIONS:`--cpu-prof --cpu-prof-dir ${s.artifactDir} --cpu-prof-name ${s.fileName} --cpu-prof-interval ${s.intervalUs}`},I=Bun.nanoseconds(),_=await Bun.spawn(U,{cwd:s.cwd,env:B,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,O=Bun.nanoseconds()-I,j=Bun.file(h);if(!await j.exists())return{diagnosticWallNs:O,exitCode:_,warnings:[{code:"artifact-missing",message:`Expected a .cpuprofile at ${h} after exit ${_}, found nothing. The workload's argv[0] must be a \`bun\` binary for CPU capture.`,data:{artifactPath:h,argv:s.argv}}]};let Y=await j.json(),L=ke(Y,"cpu-prof",s.intervalUs),K=Y.samples.length===0?[{code:"empty-profile",message:"CPU capture produced zero samples."}]:[];return{diagnosticWallNs:O,exitCode:_,artifactPath:h,cpu:L,warnings:K}}function We(s,h="heap-prof"){let{node_fields:m,node_types:T}=s.snapshot.meta,U=m.indexOf("type"),B=m.indexOf("self_size"),I=m.length,A=T[0];if(U===-1||B===-1||!Array.isArray(A))return{origin:h,typeCounts:[],objectCount:s.snapshot.node_count};let _=A.length,O=Array(_),j=new Map,Y=[],L=0,K=s.nodes,X=K.length;for(let ne=0;ne<X;ne+=I){let q=K[ne+U],Q=K[ne+B]??0;L+=Q;let Z;if(q>=0&&q<_){if(Z=O[q],Z===void 0)Z={type:A[q],count:0,bytes:0},O[q]=Z,Y.push(Z)}else{let ie=`unknown(${q})`;if(Z=j.get(ie),Z===void 0)Z={type:ie,count:0,bytes:0},j.set(ie,Z),Y.push(Z)}Z.count++,Z.bytes+=Q}let H=Y.sort((ne,q)=>q.count-ne.count),te=H.slice(0,20),re=H.slice(20),oe=te.map(({type:ne,count:q,bytes:Q})=>({type:ne,count:q,retainedBytes:Q}));if(re.length>0){let ne=0,q=0;for(let Q of re)ne+=Q.count,q+=Q.bytes;oe.push({type:"other",count:ne,retainedBytes:q})}return{origin:h,heapSizeBytes:L,objectCount:s.snapshot.node_count,typeCounts:oe}}function Pn(s,h,m){let T=["--heap-prof","--heap-prof-dir",h,"--heap-prof-name",m],U=s[0];if(U==="bun"||U?.endsWith("/bun"))return[U,...T,...s.slice(1)];return s}async function Ue(s){let h=`${s.artifactDir}/${s.fileName}`,m=s.argv[0],T=m==="bun"||m?.endsWith("/bun"),U=Pn(s.argv,s.artifactDir,s.fileName),B=T?s.env:{...process.env,...s.env,BUN_OPTIONS:`--heap-prof --heap-prof-dir ${s.artifactDir} --heap-prof-name ${s.fileName}`},I=Bun.nanoseconds(),_=await Bun.spawn(U,{cwd:s.cwd,env:B,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,O=Bun.nanoseconds()-I,j=Bun.file(h);if(!await j.exists())return{diagnosticWallNs:O,exitCode:_,warnings:[{code:"artifact-missing",message:`Expected a heap snapshot at ${h} after exit ${_}, found nothing. The workload's argv[0] must be a \`bun\` binary for heap capture.`,data:{artifactPath:h,argv:s.argv}}]};let Y=await j.json(),L=We(Y,"heap-prof");return{diagnosticWallNs:O,exitCode:_,artifactPath:h,heap:L,warnings:[]}}import{Session as kn}from"inspector/promises";var $n=1000;async function Oe(s,h={}){let m=h.intervalUs??$n,T=new kn;T.connect();let U=Bun.nanoseconds();try{await T.post("Profiler.enable"),await T.post("Profiler.setSamplingInterval",{interval:m}),await T.post("Profiler.start");let B=await s(),{profile:I}=await T.post("Profiler.stop"),A=Bun.nanoseconds()-U,_=ke(I,"inspector",m);return{result:B,cpu:_,diagnosticWallNs:A}}finally{T.disconnect()}}var Rn=10,Mn=3000000000,vn=3;function Ie(s){let h=s.warmup??vn,m=s.samples,T=s.minSamples??Rn,U=m??T,B=m!==void 0?0:s.budgetMs!==void 0?s.budgetMs*1e6:Mn,I=s.timeSource!==void 0,A=[],_=0,O=0;function j(){if(m!==void 0)return O>=m;return O>=U&&_>=B}async function Y(L,K){if(s.prepare)await k(s.prepare,{phase:L,index:K},{cwd:s.cwd,env:s.env});return D(s)}return{async warmup(){for(let L=0;L<h;L++)await Y("warmup",L)},async step(){if(j())return!1;let L=await Y("timing",O);return A.push({i:O,wallNs:L.wallNs,exitCode:L.exitCode,userNs:L.userNs,systemNs:L.systemNs,maxRssBytes:L.maxRssBytes,...L.reportedNs!==void 0&&{reportedNs:L.reportedNs}}),_+=L.wallNs,O++,!0},done:j,result(){let L=A.map((H)=>I?H.reportedNs??H.wallNs:H.wallNs),K=u(L),X=P(K,A.map((H)=>H.exitCode),I?"reported":"subprocess");return{trials:A,timing:K,warnings:X}}}}async function w(s){let h=Ie(s);await h.warmup();while(await h.step());return h.result()}var Be=new URL("./runner.ts",import.meta.url).pathname,Tn="node_modules/.cache/ostia";function v(){return Math.max(1,navigator.hardwareConcurrency||1)}async function R(s,h){let m=new Set;for(let T of s){let U=new Bun.Glob(T);for await(let B of U.scan({cwd:h,absolute:!1}))m.add(B)}return[...m].sort()}function Cn(s){if(s===void 0)return;return s==="auto"?v():s}async function N(s,h,m=process.cwd()){return{suites:s.suites.length>0?s.suites:h?.suites?await R(h.suites,m):[],budgetMs:s.budgetMs??h?.budgetMs,samples:s.samples??h?.samples,minSamples:s.minSamples??h?.minSamples,jobs:s.jobs??Cn(h?.jobs),gc:s.gc||(h?.gc??!1),cpu:s.cpu||(h?.cpu??!1),alloc:s.alloc||(h?.alloc??!1),filter:s.filter??h?.filter,isolate:s.isolate||(h?.isolate??!1),preload:s.preload.length>0?s.preload:h?.preload??[],bunFlags:s.bunFlags,outDir:s.outDir??h?.outDir,noiseCheck:s.noiseCheck,cwd:m}}async function c(s){let m=`${s.outDir??Tn}/bench-tmp`,T=s.cwd??process.cwd(),U=Math.max(1,Math.floor(s.jobs??1)),B={budgetMs:s.budgetMs,samples:s.samples,minSamples:s.minSamples,gc:s.gc,cpu:s.cpu,alloc:s.alloc,noiseCheck:s.noiseCheck},I=s.suites.map((j)=>j.startsWith("/")?j:`${T}/${j}`),A=(s.preload??[]).map((j)=>j.startsWith("/")?j:`${T}/${j}`),_=s.bunFlags??[],O=async(j,Y)=>{let L=new Set,K=0,X,H=async()=>{while(X===void 0&&K<j.length){let te=K++;try{let re=Bun.spawn(j[te],{cwd:T,stdout:"inherit",stderr:"inherit",stdin:"ignore"});L.add(re);let oe=await re.exited;if(L.delete(re),oe!==0)throw Error(`Bench suite failed: ${Y(te)} (runner exited ${oe})`)}catch(re){X??=re instanceof Error?re:Error(String(re));for(let oe of L)oe.kill()}}};if(await Promise.all(Array.from({length:Math.min(U,j.length)},H)),X)throw X};try{let j=I.map((Q)=>`${m}/${e("bench-plan",Q)}.json`),Y=I.map((Q)=>`${m}/${e("bench-primary",Q)}.json`),L=I.map((Q,Z)=>["bun",..._,Be,Q,Y[Z],JSON.stringify({...B,filter:s.filter,isolate:s.isolate,preload:A,planPath:j[Z]})]);await O(L,(Q)=>s.suites[Q]);let K=await Promise.all(j.map(async(Q)=>{let{tasks:Z}=await Bun.file(Q).json();return Z})),X=await Promise.all(Y.map(t)),H=[];for(let Q=0;Q<K.length;Q++)for(let Z of K[Q])if(Z.isolate)H.push({suiteIndex:Q,taskIds:[Z.id]});let te=H.map((Q,Z)=>`${m}/${e("bench-item",I[Q.suiteIndex],Z)}.json`),re=H.map((Q,Z)=>["bun",..._,Be,I[Q.suiteIndex],te[Z],JSON.stringify({...B,taskIds:Q.taskIds,preload:A,markIsolated:!0})]);await O(re,(Q)=>s.suites[H[Q].suiteIndex]);let oe=await Promise.all(te.map(t)),ne=[],q=[];for(let Q=0;Q<K.length;Q++){let Z=X[Q],ie=new Map;for(let ee of Z.measurements){let ae=ie.get(ee.workloadId)??[];ae.push(ee),ie.set(ee.workloadId,ae)}let se=0,ce=new Map;H.forEach((ee,ae)=>{if(ee.suiteIndex===Q)ce.set(ee.taskIds[0],oe[ae])});for(let ee of K[Q])if(ee.isolate){let ae=ce.get(ee.id),de=ae.workloads[0];ne.push(de);for(let ge of ae.measurements)if(ge.workloadId===de.id)q.push(ge)}else{let ae=Z.workloads[se];ne.push(ae),se++;for(let de of ie.get(ae.id)??[])q.push(de)}}return n(ne,q,X[0]?.environment)}finally{await Bun.spawn(["rm","-rf",m]).exited}}function J(s,h,m=8){if(m<=1)throw RangeError(`range: multiplier must be > 1, got ${m}`);if(s<=0)throw RangeError(`range: start must be > 0, got ${s}`);let T=[];for(let U=s;U<=h;U*=m)T.push(U);if(!T.includes(h))T.push(h);return T}function V(s,h){let m=Object.keys(s),T=(U,B)=>{if(U===m.length){W(B,()=>h(B));return}let I=m[U];for(let A of s[I])T(U+1,{...B,[I]:A})};T(0,{})}function In(s){let h=s>>>0;return()=>{h=h+1831565813|0;let m=Math.imul(h^h>>>15,1|h);return m=m+Math.imul(m^m>>>7,61|m)^m,((m^m>>>14)>>>0)/4294967296}}var $e=2000,Dn=2000;function _e(s){let h=s.length,m=h>>1;return h%2===0?(s[m-1]+s[m])/2:s[m]}function Ee(s,h){let m=s.length;if(m===1)return s[0];let T=h*(m-1),U=Math.floor(T),B=Math.ceil(T);if(U===B)return s[U];let I=T-U;return s[U]*(1-I)+s[B]*I}function Ae(s,h,m){if(s.length<=m)return s;let T=[...s];for(let U=0;U<m;U++){let B=U+Math.floor(h()*(T.length-U)),I=T[U];T[U]=T[B],T[B]=I}return T.slice(0,m)}function je(s,h){let m=s.length,T=new Float64Array(m);for(let U=0;U<m;U++)T[U]=s[Math.floor(h()*m)];return T.sort(),_e(T)}function Le(s,h,m={}){let T=m.seed??(Date.now()^Math.imul(s.length,2654435761))>>>0,U=In(T),B=m.iterations??Dn,I=s.length>$e||h.length>$e,A=Ae(s,U,$e),_=Ae(h,U,$e),O=new Float64Array(A);O.sort();let j=_e(O),Y=new Float64Array(B);for(let L=0;L<B;L++){let K=je(A,U),X=je(_,U);Y[L]=j===0?X-K===0?0:1/0:(X-K)/j*100}return Y.sort(),{ci95:[Ee(Y,0.025),Ee(Y,0.975)],seed:T,data:{subsampled:I,iterations:B}}}function Sn(s){let h=s<0?-1:1,m=Math.abs(s),T=0.254829592,U=-0.284496736,B=1.421413741,I=-1.453152027,A=1.061405429,_=0.3275911,O=1/(1+0.3275911*m),j=1-((((1.061405429*O+-1.453152027)*O+1.421413741)*O+-0.284496736)*O+0.254829592)*O*Math.exp(-m*m);return h*j}function Nn(s){return 0.5*(1+Sn(s/Math.SQRT2))}function He(s,h){let m=s.length,T=h.length,U=m+T,B=[...s.map((H)=>({v:H,group:0})),...h.map((H)=>({v:H,group:1}))].sort((H,te)=>H.v-te.v),I=new Float64Array(U),A=0,_=0;while(_<U){let H=_;while(H+1<U&&B[H+1].v===B[_].v)H++;let te=(_+H)/2+1;for(let oe=_;oe<=H;oe++)I[oe]=te;let re=H-_+1;if(re>1)A+=re**3-re;_=H+1}let O=0;for(let H=0;H<U;H++)if(B[H].group===0)O+=I[H];let j=O-m*(m+1)/2,Y=m*T/2,L=Math.sqrt(m*T*(U+1-A/(U*(U-1)))/12),K=L===0?0:(j-Y)/L,X=Math.min(1,Math.max(0,2*(1-Nn(Math.abs(K)))));return{u:j,z:K,pValue:X}}var l={timingPct:5,frameSelfPct:10,heapTypePct:10,minFrameSelfUs:1000,alpha:0.01,bootstrapIterations:2000},De=5;function Re(s,h){if(s===0)return h===0?0:1/0;return(h-s)/s*100}function he(s,h,m){return s.measurements.find((T)=>T.workloadId===h&&T.phase===m)}function b(s,h,m=l){let T=new Set(h.workloads.map((B)=>B.id)),U=[];for(let B of s.workloads){if(!T.has(B.id))continue;let I=M(s,h,B.id,m);if(I)U.push(I)}return U}function M(s,h,m,T=l){let U=he(s,m,"timing"),B=he(h,m,"timing"),I=he(s,m,"cpu"),A=he(h,m,"cpu"),_=he(s,m,"heap"),O=he(h,m,"heap"),j=h.workloads.find((ne)=>ne.id===m),Y=U?.id??I?.id??_?.id,L=B?.id??A?.id??O?.id??j?.id;if(!Y||!L)return;let K=!1,X=[],H=Math.max(T.timingPct,s.environment?.noise.floorPct??0,h.environment?.noise.floorPct??0),te;if(U?.timing&&j?.skipped&&!B?.timing)te={medianDeltaPct:0,meanDeltaPct:0,effectPct:0,verdict:"unchanged"},X.push({code:"skipped",message:"Candidate has no timing measurement for this workload (task.skip()); treated as unchanged.",data:{workloadId:m}});else if(U?.timing&&B?.timing){let ne=U.timing.samples,q=B.timing.samples,Q=Re(U.timing.median,B.timing.median),Z=Re(U.timing.mean,B.timing.mean);if(ne.length<De||q.length<De){let ie=Q>H?"regressed":Q<-H?"improved":"unchanged";if(ie==="regressed")K=!0;te={medianDeltaPct:Q,meanDeltaPct:Z,effectPct:Q,verdict:ie},X.push({code:"thin-comparison",message:`Only ${ne.length} baseline / ${q.length} candidate sample(s); falling back to a point-estimate threshold instead of a bootstrap CI and Mann-Whitney test (needs ${De}+ per side).`,data:{baseSamples:ne.length,candSamples:q.length}})}else{let ie=Le(ne,q,{iterations:T.bootstrapIterations}),se=He(ne,q),ce=ie.ci95[0]>H&&se.pValue<T.alpha?"regressed":ie.ci95[1]<-H&&se.pValue<T.alpha?"improved":"unchanged";if(ce==="regressed")K=!0;te={medianDeltaPct:Q,meanDeltaPct:Z,effectPct:Q,ci95:ie.ci95,pValue:se.pValue,seed:ie.seed,verdict:ce}}}let re;if(I?.cpu&&A?.cpu){let ne=new Map(I.cpu.totals.map((se)=>[I.cpu.frames[se.frameIx].key,se])),q=new Map(A.cpu.totals.map((se)=>[A.cpu.frames[se.frameIx].key,se])),Q=new Map(I.cpu.frames.map((se)=>[se.key,se.name])),Z=new Map(A.cpu.frames.map((se)=>[se.key,se.name]));re=[...new Set([...ne.keys(),...q.keys()])].map((se)=>{let ce=ne.get(se)?.selfUs??0,ee=q.get(se)?.selfUs??0;return{frameKey:se,name:Z.get(se)??Q.get(se)??se,baseSelfUs:ce,candSelfUs:ee,deltaPct:Re(ce,ee)}}).sort((se,ce)=>Math.abs(ce.deltaPct)-Math.abs(se.deltaPct));for(let se of re)if((se.baseSelfUs>=T.minFrameSelfUs||se.candSelfUs>=T.minFrameSelfUs)&&se.deltaPct>T.frameSelfPct)K=!0}let oe;if(_?.heap&&O?.heap){let ne=new Map(_.heap.typeCounts.map((Z)=>[Z.type,Z])),q=new Map(O.heap.typeCounts.map((Z)=>[Z.type,Z]));oe=[...new Set([...ne.keys(),...q.keys()])].map((Z)=>{let ie=ne.get(Z),se=q.get(Z);return{type:Z,baseCount:ie?.count??0,candCount:se?.count??0,baseBytes:ie?.retainedBytes,candBytes:se?.retainedBytes,deltaPct:Re(ie?.count??0,se?.count??0)}}).sort((Z,ie)=>Math.abs(ie.deltaPct)-Math.abs(Z.deltaPct));for(let Z of oe)if(Z.deltaPct>T.heapTypePct)K=!0}return{id:e("cmp",Y,L),baselineMeasurementId:Y,candidateMeasurementId:L,timing:te,...X.length>0&&{warnings:X},frames:re,heapTypes:oe,thresholds:{...T,effectiveTimingPct:H},verdict:K?"fail":"pass"}}function fe(s,h){if(h){let m=s.measurements.find((T)=>T.id===h);return m?.cpu?[m]:[]}return s.measurements.filter((m)=>m.phase==="cpu"&&m.cpu)}function be(s){let h=s.nodes,m=h.length,T=Fn(s),U=new Int32Array(m).fill(-1);for(let _=0;_<m;_++)for(let O of h[_].children){let j=T(O);if(j!==-1)U[j]=_}let B=[];for(let _=0;_<m;_++)if(U[_]===-1)B.push(_);let I=[],A=[];for(let _=B.length-1;_>=0;_--)A.push(B[_]);while(A.length>0){let _=A.pop();I.push(_);for(let O of h[_].children){let j=T(O);if(j!==-1&&U[j]===_)A.push(j)}}return{count:m,indexOf:T,parentIx:U,roots:B,order:I}}function Fn(s){let h=s.nodes,m=h.length,T=1/0,U=-1/0,B=!0;for(let A=0;A<m;A++){let _=h[A].id;if(!Number.isInteger(_)){B=!1;break}if(_<T)T=_;if(_>U)U=_}if(B&&m>0&&U-T<m*4+64){let A=U-T+1,_=new Int32Array(A).fill(-1);for(let O=0;O<m;O++)_[h[O].id-T]=O;return(O)=>{let j=O-T;return j>=0&&j<A?_[j]:-1}}let I=new Map;for(let A=0;A<m;A++)I.set(h[A].id,A);return(A)=>I.get(A)??-1}function Ve(s,h){let{count:m,indexOf:T,parentIx:U,order:B}=h,I=new Float64Array(m),A=new Float64Array(m),_=s.samples?.nodeIds??[],O=s.samples?.timeDeltasUs??[];for(let Y=0;Y<_.length;Y++){let L=T(_[Y]);if(L===-1)continue;I[L]+=O[Y]??0,A[L]+=1}let j=new Float64Array(m);for(let Y=B.length-1;Y>=0;Y--){let L=B[Y];j[L]+=I[L];let K=U[L];if(K>=0)j[K]+=j[L]}return{selfUs:I,totalUs:j,samples:A}}var ze={name:"collapsed",async render(s,h={}){return{files:fe(s,h.measurementId).map((U)=>{let B=U.cpu,{nodes:I,frames:A}=B,_=be(B),O=Array(_.count);for(let X of _.order){let H=A[I[X].frameIx].name||"(anonymous)",te=_.parentIx[X];O[X]=te===-1?H:`${O[te]};${H}`}let j=new Float64Array(_.count),Y=[],L=B.samples?.nodeIds??[];for(let X=0;X<L.length;X++){let H=_.indexOf(L[X]);if(H===-1)continue;if(j[H]++===0)Y.push(H)}let K=Array(Y.length);for(let X=0;X<Y.length;X++){let H=Y[X];K[X]=`${O[H]} ${j[H]}`}return{path:`${U.id}.collapsed.txt`,content:K.join(`
3
+ `)+(K.length>0?`
4
+ `:"")}})}}};var Ke={name:"cpuprofile",async render(s,h={}){let m=fe(s,h.measurementId),T=[],U=[];for(let B of m){if(B.cpu?.origin!=="cpu-prof"&&B.cpu?.origin!=="inspector"){U.push(`${B.id} (origin ${B.cpu?.origin??"unknown"} has no .cpuprofile artifact to pass through)`);continue}let I=B.artifacts.find((_)=>_.kind==="cpuprofile");if(!I){U.push(`${B.id} (no cpuprofile artifact recorded on this run)`);continue}let A=Bun.file(I.path);if(!await A.exists()){U.push(`${B.id} (artifact missing on disk: ${I.path})`);continue}T.push({path:`${B.id}.cpuprofile`,content:await A.text()})}if(T.length===0&&U.length>0)return{text:`No .cpuprofile artifacts available:
5
+ ${U.map((B)=>` - ${B}`).join(`
6
+ `)}
7
+ `};return{files:T}}};var Ge={name:"json",async render(s){return{text:S(s)}}};var Je={name:"jsonl",async render(s){let{measurements:h,...m}=s;return{text:`${[x(m),...h.map((U)=>x(U))].join(`
8
+ `)}
9
+ `}}};var Wn={ns:1,\u{b5}s:1000,ms:1e6,s:1e9};function xe(s){let h=Math.abs(s);if(h>=1e9)return"s";if(h>=1e6)return"ms";if(h>=1000)return"\xB5s";return"ns"}function Un(s){let h=Math.floor(Math.log10(Math.max(Math.abs(s),1)))+1;return Math.max(1,3-h)}function me(s,h=xe(s)){let m=s/Wn[h];return`${m.toFixed(Un(m))} ${h}`}function Me(s){return`${s.cpuModel} \xB7 ${s.cores} cores \xB7 load ${s.loadAvg1.toFixed(1)} \xB7 noise floor ${s.noise.floorPct.toFixed(1)}%`}function Ye(s){return(s/1e6).toFixed(3)}function Pe(s){return s?.label??s?.command?.join(" ")??s?.entry?.task??s?.id??"unknown"}function qe(s){if(!s?.params)return"";return` (${Object.entries(s.params).map(([m,T])=>`${m}=${T}`).join(", ")})`}function On(s){let h;for(let m of s){let T=m?.params?Object.keys(m.params):void 0;if(T?.length!==2)return;if(h===void 0)h=T;else if(T.length!==h.length||T.some((U,B)=>U!==h[B]))return}return h}var Qe=10,Xe=10,Ze={name:"markdown",async render(s){let h=new Map(s.workloads.map((I)=>[I.id,I])),m=[];m.push("# Profile Report","");let T=s.git?` \xB7 ${s.git.sha} (${s.git.branch}${s.git.dirty?", dirty":""})`:"";if(m.push(`Bun ${s.bunVersion} \xB7 ostia ${s.toolVersion} \xB7 ${s.platform.os}/${s.platform.arch} \xB7 ${s.createdAt}${T}`,""),s.environment)m.push(Me(s.environment),"");let U=s.measurements.filter((I)=>I.phase==="timing"&&I.timing!==void 0),B=s.workloads.filter((I)=>I.skipped&&!U.some((A)=>A.workloadId===I.id));if(U.length>0||B.length>0){m.push("## Timing","");let I=new Map,A=[];for(let j of U){let Y=h.get(j.workloadId)?.entry?.group;if(Y===void 0){A.push(j);continue}let L=I.get(Y);if(L)L.push(j);else I.set(Y,[j])}let _=new Map;for(let[j,Y]of I){let L=On(Y.map((K)=>h.get(K.workloadId)));if(L)_.set(j,{keys:L,runs:Y});else A.push(...Y)}if(A.length>0||B.length>0){m.push("| Task | Median | Spread (p75\u2026p99) | Mean \xB1 SD | Range | MAD |","|---|---|---|---|---|---|");for(let j of A){let Y=h.get(j.workloadId),L=Pe(Y)+qe(Y),K=j.timing,X=xe(K.median),H=K.p75??K.median,te=K.p99??K.max,re=K.mad!==void 0?me(K.mad,X):"-";m.push(`| ${L} | ${me(K.median,X)} | ${me(H,X)}\u2026${me(te,X)} | ${me(K.mean,X)} \xB1 ${me(K.stddev,X)} | ${me(K.min,X)}\u2026${me(K.max,X)} | ${re} |`)}for(let j of B){let Y=Pe(j)+qe(j);m.push(`| ${Y} | - skipped | - | - | - | - |`)}m.push("")}for(let[j,{keys:Y,runs:L}]of _){let[K,X]=Y,H=[],te=[],re=new Map;for(let oe of L){let ne=h.get(oe.workloadId).params,q=ne[K],Q=ne[X];if(!H.includes(q))H.push(q);if(!te.includes(Q))te.push(Q);re.set(`${q}\x00${Q}`,oe)}m.push(`### ${j} (${K} \xD7 ${X})`,""),m.push(`| ${K} \\ ${X} | ${te.join(" | ")} |`,`|---|${te.map(()=>"---").join("|")}|`);for(let oe of H){let ne=te.map((q)=>{let Q=re.get(`${oe}\x00${q}`);return Q?me(Q.timing.median):"-"});m.push(`| ${oe} | ${ne.join(" | ")} |`)}m.push("")}let O=U.filter((j)=>j.warnings.length>0);if(O.length>0){m.push("### Warnings","");for(let j of O){let Y=Pe(h.get(j.workloadId));for(let L of j.warnings)m.push(`- **${Y}**: ${L.message} (\`${L.code}\`)`)}m.push("")}}for(let I of s.measurements){if(I.phase!=="cpu"&&I.phase!=="heap")continue;let A=Pe(h.get(I.workloadId));if(I.phase==="cpu"){if(m.push(`## CPU capture - ${A}`,""),m.push(`instrumented, diagnostic wall ${Ye(I.diagnosticWallNs??0)}ms`,""),I.cpu){m.push(`origin: \`${I.cpu.origin}\`, interval: ${I.cpu.samplingIntervalUs}\xB5s`,""),m.push("| Self % | Self (ms) | Total (ms) | Frame |","|---|---|---|---|");let _=I.cpu.totals.reduce((O,j)=>O+j.selfUs,0)||1;for(let O of I.cpu.totals.slice(0,Qe)){let j=I.cpu.frames[O.frameIx],Y=(O.selfUs/_*100).toFixed(1);m.push(`| ${Y}% | ${(O.selfUs/1000).toFixed(2)} | ${(O.totalUs/1000).toFixed(2)} | ${j?.name||"(anonymous)"} |`)}if(m.push(""),I.jit){let O=I.jit.tiers;m.push(`JIT tiers: LLInt ${O.llint} \xB7 Baseline ${O.baseline} \xB7 DFG ${O.dfg} \xB7 FTL ${O.ftl}`,"")}}}else if(m.push(`## Heap snapshot - ${A}`,""),m.push(`instrumented, diagnostic wall ${Ye(I.diagnosticWallNs??0)}ms`,""),I.heap){m.push(`${I.heap.objectCount??"?"} objects, ${((I.heap.heapSizeBytes??0)/1e6).toFixed(2)}MB`,""),m.push("| Count | Type |","|---|---|");for(let _ of I.heap.typeCounts.slice(0,Xe))m.push(`| ${_.count} | ${_.type} |`);m.push("")}for(let _ of I.artifacts)m.push(`- artifact: \`${_.path}\``);for(let _ of I.warnings)m.push(`- ! ${_.message} (\`${_.code}\`)`);if(I.artifacts.length>0||I.warnings.length>0)m.push("")}if(s.comparisons&&s.comparisons.length>0){m.push("## Comparisons","");for(let I of s.comparisons){let A=s.measurements.find((O)=>O.id===I.candidateMeasurementId),_=Pe(A?h.get(A.workloadId):h.get(I.candidateMeasurementId));if(m.push(`### ${I.verdict==="pass"?"\u2713":"\u2717"} ${_}`,""),I.timing){let O=I.timing.medianDeltaPct>0?"+":"";m.push(`- timing: ${O}${I.timing.medianDeltaPct.toFixed(1)}% median (**${I.timing.verdict}**)`)}for(let O of I.frames?.slice(0,Qe)??[]){if(Math.abs(O.deltaPct)<0.5)continue;let j=O.deltaPct>0?"+":"";m.push(`- frame \`${O.name}\`: ${j}${O.deltaPct.toFixed(1)}% self-time (${(O.baseSelfUs/1000).toFixed(2)}ms \u2192 ${(O.candSelfUs/1000).toFixed(2)}ms)`)}for(let O of I.heapTypes?.slice(0,Xe)??[]){if(Math.abs(O.deltaPct)<0.5)continue;let j=O.deltaPct>0?"+":"";m.push(`- heap \`${O.type}\`: ${j}${O.deltaPct.toFixed(1)}% count (${O.baseCount} \u2192 ${O.candCount})`)}m.push("")}}return{text:m.join(`
10
+ `)}}};var Bn=15;function Se(s){return`n${s}`}function En(s,h,m){return`${(s||"(anonymous)").replace(/"/g,"'")} (self ${(h/1000).toFixed(2)}ms, total ${(m/1000).toFixed(2)}ms)`}function An(s,h,m,T){let U=[];if(T<=0)return U;for(let B=0;B<h;B++){if(B===m)continue;let I=s[B];if(U.length===T&&I<=s[U[T-1]])continue;let A=U.length;while(A>0&&s[U[A-1]]<I)A--;if(U.splice(A,0,B),U.length>T)U.pop()}return U}var en={name:"mermaid",async render(s,h={}){let m=h.topN??Bn;return{files:fe(s,h.measurementId).map((B)=>{let I=B.cpu,{nodes:A,frames:_}=I,O=be(I),{selfUs:j,totalUs:Y}=Ve(I,O),{parentIx:L}=O,K=O.roots[0]??-1,X=An(j,O.count,K,m),H=new Set(K!==-1?[K]:[]),te=[];for(let oe of X){te.length=0;for(let ne=oe;ne!==-1;ne=L[ne])te.push(ne);for(let ne=te.length-1;ne>=0;ne--)H.add(te[ne])}let re=["graph TD"];for(let oe of H){let ne=A[oe].id;re.push(` ${Se(ne)}["${En(_[A[oe].frameIx].name,j[oe],Y[oe])}"]`)}for(let oe of H){let ne=L[oe];if(ne!==-1&&H.has(ne))re.push(` ${Se(A[ne].id)} --> ${Se(A[oe].id)}`)}return{path:`${B.id}.mermaid.md`,content:`${re.join(`
11
+ `)}
12
+ `}})}}};function nn(s){if(!s?.entry)return;if(s.entry.group!==void 0)return s.entry.group;let h=s.entry.task,m=h.lastIndexOf("/");return m===-1?void 0:h.slice(0,m)}function ve(s){let h=Math.min(...s.map((U)=>U.run.timing.median)),m=new Map;for(let U of s){let B=nn(U.workload);if(B===void 0)continue;let I=m.get(B);if(I)I.push(U);else m.set(B,[U])}let T=new Map;for(let U of s){let B=nn(U.workload);if(B===void 0){T.set(U,h);continue}let I=m.get(B)??[U],A=I.find((_)=>_.workload?.baseline);T.set(U,A?A.run.timing.median:Math.min(...I.map((_)=>_.run.timing.median)))}return T}function ue(s){return Number.isFinite(s)?Number(s.toPrecision(6)):s}function jn(s,h){return s?.entry?.task??s?.label??s?.command?.join(" ")??h.workloadId}function _n(s,h){let m={task:s.entry?.task??s.label??s.id,skipped:!0,warnings:[]};if(s.entry?.group!==void 0)m.group=s.entry.group;if(s.description!==void 0)m.description=s.description;if(s.groupDescription!==void 0)m.groupDescription=s.groupDescription;if(s.params!==void 0)m.params=s.params;if(h?.timing)m.delta={medianPct:ue(h.timing.medianDeltaPct),meanPct:ue(h.timing.meanDeltaPct),verdict:h.timing.verdict,pass:h.verdict==="pass"};return m}function Ln(s){let h=new Map(s.workloads.map((O)=>[O.id,O])),m=s.measurements.filter((O)=>O.phase==="timing"&&O.timing!==void 0).map((O)=>({run:O,workload:h.get(O.workloadId)})),T=m.length>1?ve(m):void 0,U=new Map((s.comparisons??[]).map((O)=>[O.candidateMeasurementId,O])),B=new Set(m.map((O)=>O.run.workloadId)),I=new Map;for(let O of s.measurements){if(O.phase!=="cpu"||O.warnings.length===0)continue;let j=I.get(O.workloadId)??[];I.set(O.workloadId,[...j,...O.warnings])}let A=s.workloads.filter((O)=>O.skipped&&!B.has(O.id)).map((O)=>_n(O,U.get(O.id)));return[...m.map((O)=>{let{run:j,workload:Y}=O,L=j.timing,K={task:jn(Y,j),unit:"ns",samples:L.samples.length,mean:ue(L.mean),median:ue(L.median),stddev:ue(L.stddev),stddevPct:ue(L.mean===0?0:L.stddev/L.mean*100),min:ue(L.min),max:ue(L.max),warnings:[...j.warnings,...I.get(j.workloadId)??[]].map((H)=>H.data?{code:H.code,data:H.data}:{code:H.code})};if(L.p75!==void 0)K.p75=ue(L.p75);if(L.p99!==void 0)K.p99=ue(L.p99);if(L.mad!==void 0)K.mad=ue(L.mad);if(Y?.entry?.group!==void 0)K.group=Y.entry.group;if(Y?.description!==void 0)K.description=Y.description;if(Y?.groupDescription!==void 0)K.groupDescription=Y.groupDescription;if(Y?.params!==void 0)K.params=Y.params;if(T)K.relative=ue(L.median/(T.get(O)??L.median));if(Y?.baseline)K.baseline=!0;let X=U.get(j.id);if(X?.timing){if(K.delta={medianPct:ue(X.timing.medianDeltaPct),meanPct:ue(X.timing.meanDeltaPct),verdict:X.timing.verdict,pass:X.verdict==="pass"},X.timing.ci95)K.delta.ci95=[ue(X.timing.ci95[0]),ue(X.timing.ci95[1])];if(X.timing.pValue!==void 0)K.delta.pValue=ue(X.timing.pValue)}return K}),...A]}var tn={name:"minimal",async render(s){let h=Ln(s).map((m)=>JSON.stringify(m));return{text:h.length>0?`${h.join(`
13
+ `)}
14
+ `:""}}};var Hn="https://www.speedscope.app/file-format-schema.json";function rn(s){return s?.label??s?.command?.join(" ")??s?.entry?.task??"profile"}var sn={name:"speedscope",async render(s,h={}){let m=fe(s,h.measurementId),T=new Map(s.workloads.map((B)=>[B.id,B]));return{files:m.map((B)=>{let I=B.cpu,{nodes:A}=I,_=be(I),O=I.samples?.nodeIds??[],j=I.samples?.timeDeltasUs??[],Y=Array(_.count);for(let H of _.order){let te=_.parentIx[H],re=A[H].frameIx;Y[H]=te===-1?[re]:[...Y[te],re]}let L=Array(O.length);for(let H=0;H<O.length;H++){let te=_.indexOf(O[H]);L[H]=te===-1?[]:Y[te]}let K=0;for(let H=0;H<j.length;H++)K+=j[H];let X={$schema:Hn,exporter:"ostia",name:rn(T.get(B.workloadId)),activeProfileIndex:0,shared:{frames:I.frames.map((H)=>({name:H.name||"(anonymous)",file:H.url,line:H.line!==void 0?H.line+1:void 0}))},profiles:[{type:"sampled",name:rn(T.get(B.workloadId)),unit:"microseconds",startValue:0,endValue:K,samples:L,weights:j}]};return{path:`${B.id}.speedscope.json`,content:`${JSON.stringify(X,null,2)}
15
+ `}})}}};function Vn(s){return(s/1e6).toFixed(3)}function zn(s){if(s<1024)return`${s.toFixed(0)}B`;if(s<1048576)return`${(s/1024).toFixed(2)}KB`;return`${(s/1048576).toFixed(2)}MB`}function Te(s){return s.label??s.command?.join(" ")??s.entry?.task??s.id}function Kn(s){if(!s?.entry)return;if(s.entry.group!==void 0)return s.entry.group;let h=s.entry.task,m=h.lastIndexOf("/");return m===-1?void 0:h.slice(0,m)}var an={name:"table",async render(s){let h=s.measurements.filter((ee)=>ee.phase==="timing"&&ee.timing!==void 0),m=new Map(s.workloads.map((ee)=>[ee.id,ee])),T=s.environment?[Me(s.environment),""]:[],U=s.workloads.filter((ee)=>ee.skipped&&!h.some((ae)=>ae.workloadId===ee.id));if(h.length===0&&U.length===0){let ee=on(s,m);return{text:ee.length>0?`${[...T,...ee].join(`
16
+ `)}
17
+ `:`(no timing runs)
18
+ `}}let B=new Map(h.map((ee)=>[ee.workloadId,ee])),I=[];for(let ee of s.workloads){let ae=B.get(ee.id);if(ae)I.push({kind:"measured",run:ae,workload:ee,label:Te(ee)});else if(ee.skipped)I.push({kind:"skipped",workload:ee,label:Te(ee)})}let A=I.filter((ee)=>ee.kind==="measured"),_=new Map(s.measurements.filter((ee)=>ee.phase==="memstats"&&ee.memory?.bytesPerOp!==void 0).map((ee)=>[ee.workloadId,ee.memory.bytesPerOp])),O=_.size>0,j=A.length>1,Y=ve(A),L=new Map,K=new Map,X;for(let ee of I){let ae=Kn(ee.workload);if(ae!==X){if(ae!==void 0)K.set(ee,ae);X=ae}L.set(ee,ae!==void 0?" ":"")}let H=Math.max(4,...I.map((ee)=>L.get(ee).length+ee.label.length)),te=10,re=18,oe=18,ne=10,q=[...T],Q=O?` ${"Alloc/op".padEnd(ne)}`:"",Z=`${"Task".padEnd(H)} ${"Median".padEnd(te)} ${"Spread".padEnd(re)} ${"Range".padEnd(oe)}${Q}${j?" Relative":""}`;q.push(Z),q.push("-".repeat(Z.length));let ie=[];for(let ee of I){let ae=K.get(ee);if(ae!==void 0)q.push(`${ae}:`);let de=L.get(ee);if(ee.kind==="skipped"){q.push(`${(de+ee.label).padEnd(H)} - skipped`);continue}let{run:ge,label:ln,workload:Ce}=ee,pe=ge.timing,ye=xe(pe.median),dn=pe.p75??pe.median,fn=pe.p99??pe.max,gn=me(pe.median,ye),hn=`${me(dn,ye)}\u2026${me(fn,ye)}`,bn=`${me(pe.min,ye)}\u2026${me(pe.max,ye)}`,we=`${(de+ln).padEnd(H)} ${gn.padEnd(te)} ${hn.padEnd(re)} ${bn.padEnd(oe)}`;if(O){let le=Ce?_.get(Ce.id):void 0,yn=le!==void 0?zn(le):"";we+=` ${yn.padEnd(ne)}`}if(j){let le=pe.median/(Y.get(ee)??pe.median);if(le===1)we+=Ce?.baseline?" 1.00\xD7 (baseline)":" 1.00\xD7";else if(le>1)we+=` ${le.toFixed(2)}\xD7 slower`;else we+=` ${(1/le).toFixed(2)}\xD7 faster`}if(q.push(we),ge.warnings.length>0)q.push(`${" ".repeat(de.length)} ! ${ge.warnings.map((le)=>le.code).join(", ")}`),ie.push(ee)}if(ie.length>0){q.push(""),q.push("Warnings:");for(let ee of ie)for(let ae of ee.run.warnings)q.push(` ${ee.label}: ${ae.message}`)}let se=Jn(s,m);if(se.length>0)q.push(""),q.push(...se);let ce=on(s,m);if(ce.length>0)q.push(""),q.push(...ce);return{text:`${q.map((ee)=>ee.trimEnd()).join(`
19
+ `)}
20
+ `}}};function Gn(s,h,m){let T=s.measurements.find((B)=>B.id===m),U=T?h.get(T.workloadId):h.get(m);return U?Te(U):m}function on(s,h){if(!s.comparisons||s.comparisons.length===0)return[];let m=[];for(let T of s.comparisons){let U=Gn(s,h,T.candidateMeasurementId),B=T.verdict==="pass"?"\u2713":"\u2717";if(m.push(`${B} ${U}`),T.timing){let I=(A)=>`${A>=0?"+":""}${A.toFixed(1)}%`;if(T.timing.ci95&&T.timing.pValue!==void 0){let A=T.timing.pValue<0.001?"p<0.001":`p=${T.timing.pValue.toFixed(3)}`;m.push(` timing: ${I(T.timing.medianDeltaPct)} median, 95% CI [${I(T.timing.ci95[0])}, ${I(T.timing.ci95[1])}], ${A} (${T.timing.verdict})`)}else m.push(` timing: ${I(T.timing.medianDeltaPct)} median (${T.timing.verdict})`)}if(T.frames)for(let I of T.frames.slice(0,cn)){if(Math.abs(I.deltaPct)<0.5)continue;let A=I.deltaPct>0?"+":"";m.push(` frame ${I.name}: ${A}${I.deltaPct.toFixed(1)}% self-time (${(I.baseSelfUs/1000).toFixed(2)}ms -> ${(I.candSelfUs/1000).toFixed(2)}ms)`)}if(T.heapTypes)for(let I of T.heapTypes.slice(0,un)){if(Math.abs(I.deltaPct)<0.5)continue;let A=I.deltaPct>0?"+":"";m.push(` heap ${I.type}: ${A}${I.deltaPct.toFixed(1)}% count (${I.baseCount} -> ${I.candCount})`)}}return m}var cn=5,un=5;function Jn(s,h){let m=[];for(let T of s.measurements){if(T.phase!=="cpu"&&T.phase!=="heap")continue;let U=h.get(T.workloadId),B=U?Te(U):T.workloadId;if(T.phase==="cpu")if(T.cpu){m.push(`CPU capture - ${B} (instrumented, ${T.cpu.samplingIntervalUs}\xB5s interval, diagnostic wall ${Vn(T.diagnosticWallNs??0)}ms)`);let I=T.cpu.totals.reduce((A,_)=>A+_.selfUs,0)||1;for(let A of T.cpu.totals.slice(0,cn)){let _=T.cpu.frames[A.frameIx],O=(A.selfUs/I*100).toFixed(1);m.push(` ${O.padStart(5)}% ${(A.selfUs/1000).toFixed(2).padStart(8)}ms self ${_?.name??"?"}`)}}else m.push(`CPU capture - ${B} (instrumented, no evidence captured)`);else if(T.heap){let I=((T.heap.heapSizeBytes??0)/1e6).toFixed(2);m.push(`Heap snapshot - ${B} (instrumented, ${T.heap.objectCount??"?"} objects, ${I}MB)`);for(let A of T.heap.typeCounts.slice(0,un))m.push(` ${String(A.count).padStart(6)} ${A.type}`)}else m.push(`Heap snapshot - ${B} (instrumented, no evidence captured)`);for(let I of T.artifacts)m.push(` artifact: ${I.path}`);for(let I of T.warnings)m.push(` ! ${I.message}`)}return m}var r={table:an,json:Ge,markdown:Ze,jsonl:Je,minimal:tn,collapsed:ze,mermaid:en,speedscope:sn,cpuprofile:Ke};function G(s){return s}var Yn="node_modules/.cache/ostia",Ne=1000;async function C(s){let h=o({samples:s.samples??null,budgetMs:s.budgetMs??null,minSamples:s.minSamples??null,warmup:s.warmup??null,cpu:s.cpu??!1,heap:s.heap??!1,cpuIntervalUs:s.cpuIntervalUs??Ne}),T=`${s.outDir??Yn}/artifacts`,U=s.noiseCheck===!1?void 0:f(),B=U?g(U):void 0,I=[],A=[],_=s.commands.map((Y)=>{let L=typeof Y==="string"||Array.isArray(Y)?{command:Y}:Y,K=Array.isArray(L.command)?L.command:y(L.command),X=L.prepare??s.prepare,H=L.timeSource??s.timeSource,te=p(K,L.label??(Array.isArray(L.command)?void 0:L.command),{prepare:X,timeSource:H});return{argv:K,workload:te,prepare:X,timeSource:H}}),O=(s.interleave??!0)&&_.length>1,j=(Y)=>({argv:Y.argv,cwd:s.cwd,env:s.env,samples:s.samples,budgetMs:s.budgetMs,minSamples:s.minSamples,warmup:s.warmup,prepare:Y.prepare,timeSource:Y.timeSource});if(O){let Y=_.map((K)=>Ie(j(K)));for(let K of Y)await K.warmup();let L=!0;while(L){L=!1;for(let K of Y)if(await K.step())L=!0}for(let K=0;K<_.length;K++){let{argv:X,workload:H,prepare:te}=_[K];I.push(H);let re=Y[K].result(),oe=i({workload:H,configFingerprint:h,trials:re.trials,timing:re.timing,warnings:B&&A.length===0?[...re.warnings,B]:re.warnings,interleaved:!0});A.push(oe),A.push(...await mn(H,X,oe.id,h,s,T,te))}return n(I,A,U)}for(let Y of _){let{argv:L,workload:K,prepare:X}=Y;I.push(K);let H=await w(j(Y)),te=i({workload:K,configFingerprint:h,trials:H.trials,timing:H.timing,warnings:B&&A.length===0?[...H.warnings,B]:H.warnings});A.push(te),A.push(...await mn(K,L,te.id,h,s,T,X))}return n(I,A,U)}async function mn(s,h,m,T,U,B,I){let A=[],_=async(O)=>{if(I)await k(I,{phase:O,index:0},{cwd:U.cwd,env:U.env})};if(U.cpu){await _("cpu");let O=`${m}-cpu.cpuprofile`,j=await Fe({argv:h,cwd:U.cwd,env:U.env,artifactDir:B,fileName:O,intervalUs:U.cpuIntervalUs??Ne});A.push(await pn({workload:s,phase:"cpu",configFingerprint:T,diagnosticWallNs:j.diagnosticWallNs,exitCode:j.exitCode,cpu:j.cpu,artifactPath:j.artifactPath,artifactKind:"cpuprofile",warnings:j.warnings}))}if(U.heap){await _("heap");let O=`${m}-heap.heapsnapshot`,j=await Ue({argv:h,cwd:U.cwd,env:U.env,artifactDir:B,fileName:O});A.push(await pn({workload:s,phase:"heap",configFingerprint:T,diagnosticWallNs:j.diagnosticWallNs,exitCode:j.exitCode,heap:j.heap,artifactPath:j.artifactPath,artifactKind:"heapsnapshot",warnings:j.warnings}))}return A}async function pn(s){let h=`${s.workload.id}-${s.phase}-${s.configFingerprint}`,m=s.artifactPath?[await E(h,s.artifactKind,s.artifactPath)]:[];return a({workload:s.workload,phase:s.phase,configFingerprint:s.configFingerprint,diagnosticWallNs:s.diagnosticWallNs,exitCode:s.exitCode,cpu:s.cpu,heap:s.heap,warnings:s.warnings,artifacts:m})}async function z(s,h={}){let m=F(s),T=o({intervalUs:h.intervalUs??Ne,origin:h.origin??"inspector"}),U=(O)=>O.samples?.nodeIds.length===0?[{code:"empty-profile",message:"In-process capture produced zero samples."}]:[];if(h.origin==="jsc"){let{result:O,cpu:j,jit:Y,diagnosticWallNs:L}=await d(s,h),K=a({workload:m,phase:"cpu",configFingerprint:T,diagnosticWallNs:L,cpu:j,jit:Y,warnings:U(j),artifacts:[]});return{result:O,measurement:K,document:n([m],[K])}}let{result:B,cpu:I,diagnosticWallNs:A}=await Oe(s,h),_=a({workload:m,phase:"cpu",configFingerprint:T,diagnosticWallNs:A,cpu:I,warnings:U(I),artifacts:[]});return{result:B,measurement:_,document:n([m],[_])}}
21
+ export{v,R,N,c,l,b,M,w,J,V,r,G,C,z};
package/cli.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{P,T,I,c,l,b,v,w,s,R}from"./chunk-r5b8vf8w.js";import{e,m,n,p,i,o,r,t}from"./chunk-qbt85kmg.js";function G(a){return e("cache",a.workloadId,a.phase,a.configFingerprint,a.bunVersion,a.toolVersion,a.instrumented,a.inputsDigest??null)}async function z(a,u=process.cwd()){if(a.length===0)return;let d=new Set;for(let g of a){let k=new Bun.Glob(g);for await(let y of k.scan({cwd:u,absolute:!1}))d.add(y)}let f=[...d].sort(),h=await Promise.all(f.map(async(g)=>{let k=await Bun.file(`${u}/${g}`).arrayBuffer();return{path:g,sha256:Bun.CryptoHasher.hash("sha256",k,"hex")}}));return e("inputs",h)}function K(a,u){return`${a}/cache/${u}.json`}async function Z(a,u){let d=Bun.file(K(a,u));if(!await d.exists())return;return await d.json()}async function X(a,u,d){await Bun.write(K(a,u),`${JSON.stringify(d,null,2)}
4
- `)}var le="node_modules/.cache/ostia",ce=".ostia/baselines",ue={runs:null,warmup:3,outDir:le,baselineDir:ce,baseline:"main",cpuIntervalUs:1000,thresholds:l,workloads:[]};function ee(a){return{...ue,...a,thresholds:{...l,...a.thresholds??{}}}}async function Q(a){let u=Bun.file(a);if(!await u.exists())return;return ee(await u.json())}async function Y(a){let u=a.startsWith("/")?a:`${process.cwd()}/${a}`;if(!await Bun.file(u).exists())return;let d=await import(u);return ee(d.default??{})}async function U(a){if(a!==void 0)return a.endsWith(".ts")?Y(a):Q(a);return await Y("ostia.config.ts")??Q("ostia.config.json")}function M(a,u){return`${a.baselineDir}/${u??a.baseline}.json`}class H extends Error{path;constructor(a){super(`No baseline document at ${a}. Create one with: ostia time --export-json ${a} <command...>`);this.path=a}}async function _(a,u){let d=[];for(let f of a.workloads){if(f.suites){let j=await T(f.suites,process.cwd()),A=await c({suites:j,outDir:a.outDir,noiseCheck:!1,budgetMs:a.bench?.budgetMs,samples:a.bench?.samples,minSamples:a.bench?.minSamples,gc:a.bench?.gc,cpu:a.bench?.cpu,alloc:a.bench?.alloc,filter:a.bench?.filter,isolate:a.bench?.isolate,preload:a.bench?.preload,jobs:typeof a.bench?.jobs==="number"?a.bench.jobs:void 0});for(let E of A.workloads){let C=A.measurements.find((B)=>B.workloadId===E.id&&B.phase==="timing");if(!C)continue;d.push({workload:E,status:"executed",run:C})}continue}let h=p(f.command,f.label),g=await z(f.inputs??[]),k=o({runs:a.runs,warmup:a.warmup}),y=G({workloadId:h.id,phase:"timing",configFingerprint:k,bunVersion:Bun.version,toolVersion:m,instrumented:!1,inputsDigest:g}),D=u?void 0:await Z(a.outDir,y),x,N;if(D)x=D,N="cached";else{let j=await w({argv:f.command,samples:a.runs??void 0,warmup:a.warmup});x=i({workload:h,configFingerprint:k,trials:j.trials,timing:j.timing,warnings:j.warnings}),await X(a.outDir,y,x),N="executed"}d.push({workload:h,status:N,run:x})}return d}async function te(a){let{config:u}=a,d=M(u,a.baselineName);if(!await Bun.file(d).exists())throw new H(d);let h=await t(d),k=(await _(u,a.full)).map((C)=>({...C})),y=k.filter((C)=>C.status==="executed").length,D=k.filter((C)=>C.status==="cached").length,x=y,N=n(k.map((C)=>C.workload),k.map((C)=>C.run)),j=0,A=0,E=0;for(let C of k){let B=v(h,N,C.workload.id,u.thresholds);if(!B){E++;continue}if(C.comparison=B,B.verdict==="pass")j++;else A++}return N.comparisons=k.map((C)=>C.comparison).filter((C)=>C!==void 0),{document:N,summary:{total:k.length,affected:y,cached:D,executed:x,passed:j,regressed:A,missingBaseline:E,results:k}}}function se(a){let u=[];if(u.push(`${a.total} workloads`),u.push(`${a.affected} affected by this change`),u.push(`${a.cached} cached`),u.push(`${a.executed} executed`),a.missingBaseline>0)u.push(`${a.missingBaseline} skipped (no matching baseline workload)`);let d=a.results.filter((f)=>f.comparison?.verdict==="fail").map((f)=>{let h=f.comparison.timing,g=f.workload.label??f.workload.command?.join(" ")??f.workload.id;return h?`${h.medianDeltaPct>0?"+":""}${h.medianDeltaPct.toFixed(1)}% median on ${g}`:g});return u.push(`${a.passed} passed ${a.regressed} regressed${d.length>0?` (${d.join(", ")})`:""}`),u.push(""),u.push(`Profile CI: ${a.regressed>0?"\u2717":"\u2713"}`),`${u.join(`
3
+ import{v,R,N,c,l,b,M,w,r,C}from"./chunk-h6579788.js";import{e,m,n,p,i,o,s,t}from"./chunk-9dqf5cxf.js";function G(u){return e("cache",u.workloadId,u.phase,u.configFingerprint,u.bunVersion,u.toolVersion,u.instrumented,u.inputsDigest??null)}async function z(u,a=process.cwd()){if(u.length===0)return;let f=new Set;for(let k of u){let g=new Bun.Glob(k);for await(let y of g.scan({cwd:a,absolute:!1}))f.add(y)}let d=[...f].sort(),h=await Promise.all(d.map(async(k)=>{let g=await Bun.file(`${a}/${k}`).arrayBuffer();return{path:k,sha256:Bun.CryptoHasher.hash("sha256",g,"hex")}}));return e("inputs",h)}function K(u,a){return`${u}/cache/${a}.json`}async function X(u,a){let f=Bun.file(K(u,a));if(!await f.exists())return;return await f.json()}async function Z(u,a,f){await Bun.write(K(u,a),`${JSON.stringify(f,null,2)}
4
+ `)}var ce="node_modules/.cache/ostia",ue=".ostia/baselines",me={runs:null,warmup:3,outDir:ce,baselineDir:ue,baseline:"main",cpuIntervalUs:1000,thresholds:l,workloads:[]};function ee(u){return{...me,...u,thresholds:{...l,...u.thresholds??{}}}}async function Q(u){let a=Bun.file(u);if(!await a.exists())return;return ee(await a.json())}async function Y(u){let a=u.startsWith("/")?u:`${process.cwd()}/${u}`;if(!await Bun.file(a).exists())return;let f=await import(a);return ee(f.default??{})}async function O(u){if(u!==void 0)return u.endsWith(".ts")?Y(u):Q(u);return await Y("ostia.config.ts")??Q("ostia.config.json")}function U(u,a){return`${u.baselineDir}/${a??u.baseline}.json`}class L extends Error{path;constructor(u){super(`No baseline document at ${u}. Create one with: ostia time --export-json ${u} <command...>`);this.path=u}}async function V(u,a){let f=[];for(let d of u.workloads){if(d.suites){let j=await R(d.suites,process.cwd()),F=await c({suites:j,outDir:u.outDir,noiseCheck:!1,budgetMs:u.bench?.budgetMs,samples:u.bench?.samples,minSamples:u.bench?.minSamples,gc:u.bench?.gc,cpu:u.bench?.cpu,alloc:u.bench?.alloc,filter:u.bench?.filter,isolate:u.bench?.isolate,preload:u.bench?.preload,jobs:typeof u.bench?.jobs==="number"?u.bench.jobs:void 0});for(let P of F.workloads){let A=F.measurements.find((B)=>B.workloadId===P.id&&B.phase==="timing");if(!A)continue;f.push({workload:P,status:"executed",run:A})}continue}let h=p(d.command,d.label,{prepare:d.prepare,timeSource:d.timeSource}),k=await z(d.inputs??[]),g=o({runs:u.runs,warmup:u.warmup}),y=typeof d.prepare!=="function",E=G({workloadId:h.id,phase:"timing",configFingerprint:g,bunVersion:Bun.version,toolVersion:m,instrumented:!1,inputsDigest:k}),S=a||!y?void 0:await X(u.outDir,E),D,T;if(S)D=S,T="cached";else{let j=await w({argv:d.command,samples:u.runs??void 0,warmup:u.warmup,prepare:d.prepare,timeSource:d.timeSource});if(D=i({workload:h,configFingerprint:g,trials:j.trials,timing:j.timing,warnings:j.warnings}),y)await Z(u.outDir,E,D);T="executed"}f.push({workload:h,status:T,run:D})}return f}async function te(u){let{config:a}=u,f=U(a,u.baselineName);if(!await Bun.file(f).exists())throw new L(f);let h=await t(f),g=(await V(a,u.full)).map((P)=>({...P})),y=g.filter((P)=>P.status==="executed").length,E=g.filter((P)=>P.status==="cached").length,S=y,D=n(g.map((P)=>P.workload),g.map((P)=>P.run)),T=0,j=0,F=0;for(let P of g){let A=M(h,D,P.workload.id,a.thresholds);if(!A){F++;continue}if(P.comparison=A,A.verdict==="pass")T++;else j++}return D.comparisons=g.map((P)=>P.comparison).filter((P)=>P!==void 0),{document:D,summary:{total:g.length,affected:y,cached:E,executed:S,passed:T,regressed:j,missingBaseline:F,results:g}}}function se(u){let a=[];if(a.push(`${u.total} workloads`),a.push(`${u.affected} affected by this change`),a.push(`${u.cached} cached`),a.push(`${u.executed} executed`),u.missingBaseline>0)a.push(`${u.missingBaseline} skipped (no matching baseline workload)`);let f=u.results.filter((d)=>d.comparison?.verdict==="fail").map((d)=>{let h=d.comparison.timing,k=d.workload.label??d.workload.command?.join(" ")??d.workload.id;return h?`${h.medianDeltaPct>0?"+":""}${h.medianDeltaPct.toFixed(1)}% median on ${k}`:k});return a.push(`${u.passed} passed ${u.regressed} regressed${f.length>0?` (${f.join(", ")})`:""}`),a.push(""),a.push(`Profile CI: ${u.regressed>0?"\u2717":"\u2713"}`),`${a.join(`
5
5
  `)}
6
- `}async function ne(a,u){let d=await _(a,!1),f=n(d.map((g)=>g.workload),d.map((g)=>g.run)),h=M(a,u);return await r(f,h),h}async function re(a){let u=[];try{let f=new Bun.Glob("*.json");for await(let h of f.scan({cwd:a.baselineDir,absolute:!1}))u.push(h.replace(/\.json$/,""))}catch{return[]}u.sort();let d=[];for(let f of u){let h=M(a,f);try{let g=await t(h);d.push({name:f,path:h,createdAt:g.createdAt,toolVersion:g.toolVersion,bunVersion:g.bunVersion,workloads:g.workloads.length,...g.git!==void 0&&{git:g.git}})}catch{}}return d}async function L(a,u){if(a.text)process.stdout.write(a.text);if(!a.files||a.files.length===0)return;if(u)for(let d of a.files){let f=d.path?`${u}/${d.path}`:u;await Bun.write(f,d.content),process.stdout.write(`wrote ${f}
7
- `)}else if(a.files.length===1)process.stdout.write(a.files[0].content);else for(let d of a.files)process.stdout.write(`--- ${d.path??"(unnamed)"} ---
8
- ${d.content}
9
- `)}var me=`ostia time [flags] <command...>
6
+ `}async function ne(u,a){let f=await V(u,!1),d=n(f.map((k)=>k.workload),f.map((k)=>k.run)),h=U(u,a);return await s(d,h),h}async function re(u){let a=[];try{let d=new Bun.Glob("*.json");for await(let h of d.scan({cwd:u.baselineDir,absolute:!1}))a.push(h.replace(/\.json$/,""))}catch{return[]}a.sort();let f=[];for(let d of a){let h=U(u,d);try{let k=await t(h);f.push({name:d,path:h,createdAt:k.createdAt,toolVersion:k.toolVersion,bunVersion:k.bunVersion,workloads:k.workloads.length,...k.git!==void 0&&{git:k.git}})}catch{}}return f}async function q(u,a){if(u.text)process.stdout.write(u.text);if(!u.files||u.files.length===0)return;if(a)for(let f of u.files){let d=f.path?`${a}/${f.path}`:a;await Bun.write(d,f.content),process.stdout.write(`wrote ${d}
7
+ `)}else if(u.files.length===1)process.stdout.write(u.files[0].content);else for(let f of u.files)process.stdout.write(`--- ${f.path??"(unnamed)"} ---
8
+ ${f.content}
9
+ `)}var de=`ostia time [flags] <command...>
10
10
 
11
11
  Time one or more commands N times with warmup and report timing statistics.
12
12
 
@@ -24,6 +24,17 @@ Flags:
24
24
  neighbor process) evenly across every command instead of favoring
25
25
  whichever ran first or last. Meaningless (and ignored) with one
26
26
  command. Interleaved measurements carry Measurement.interleaved: true.
27
+ --prepare CMD run CMD before every trial (warmup and --cpu/--heap trials
28
+ included), unmeasured, in the same cwd; it must exit 0. Whitespace-
29
+ split like the commands themselves (no shell). Given once it applies
30
+ to every command; given once per command it pairs up in order, so the
31
+ same command can be timed warm and cold side by side.
32
+ --time-source REGEX take each trial's time from the first REGEX match in the command's
33
+ own stdout (then stderr), capture group 1, instead of its wall clock -
34
+ e.g. --time-source "built in (\\d+)ms" for a build tool whose own
35
+ summary excludes runtime startup. Every trial must match or the run
36
+ aborts. Trials keep wallNs alongside the reported value.
37
+ --time-unit UNIT unit of the --time-source number: ns | us | ms | s (default: ms)
27
38
  --cpu capture one instrumented CPU-profile trial (subprocess --cpu-prof)
28
39
  --heap capture one instrumented heap-snapshot trial (subprocess --heap-prof)
29
40
  --cpu-interval USEC CPU sampling interval in microseconds (default: 1000)
@@ -41,6 +52,8 @@ Examples:
41
52
  ostia time "bun ./fixtures/work.ts"
42
53
  ostia time --samples 25 --warmup 3 "bun a.ts" "bun b.ts"
43
54
  ostia time --no-interleave "bun a.ts" "bun b.ts"
55
+ ostia time --prepare "rm -rf dist" "bun build.ts"
56
+ ostia time --time-source "built in (\\d+)ms" "bun build.ts"
44
57
  ostia time --cpu --heap "bun src/server.ts"
45
58
  ostia time --format json "bun a.ts"
46
59
  `,oe=`ostia bench [flags] <suite.ts...>
@@ -167,7 +180,7 @@ Flags:
167
180
  Examples:
168
181
  ostia compare before.json after.json
169
182
  ostia compare after.json --baseline .ostia/baselines/main.json
170
- `,de=`ostia report <document.json> [flags]
183
+ `,pe=`ostia report <document.json> [flags]
171
184
 
172
185
  Render a saved ProfileDocument. Files, not a GUI for the visualization formats -
173
186
  hand the output to speedscope.app, flamegraph.pl, or a Mermaid renderer.
@@ -195,7 +208,7 @@ Examples:
195
208
  ostia report doc.json --format markdown
196
209
  ostia report doc.json --format speedscope --out-dir node_modules/.cache/ostia/viz
197
210
  ostia report doc.json --format collapsed | flamegraph.pl > flame.svg
198
- `,pe=`ostia ci [--full] [--baseline NAME] [--save-baseline]
211
+ `,fe=`ostia ci [--full] [--baseline NAME] [--save-baseline]
199
212
 
200
213
  Load ostia.config.json, run configured workloads (reusing cached results when their
201
214
  fingerprint is unchanged), compare against the named baseline, and gate on regressions.
@@ -211,7 +224,7 @@ Flags:
211
224
  --help show this message
212
225
 
213
226
  Exit codes: 0 pass, 1 regression, 2 harness error (missing config/baseline, spawn failure).
214
- `,q=`ostia baseline <save|list|show> [args]
227
+ `,_=`ostia baseline <save|list|show> [args]
215
228
 
216
229
  Manage the baseline ProfileDocuments "ostia ci" gates against and "ostia compare --baseline"
217
230
  reads.
@@ -230,30 +243,33 @@ Examples:
230
243
  ostia baseline list
231
244
  ostia baseline show main
232
245
  ostia baseline show main --format markdown
233
- `;function fe(a){let u=[],d,f,h,g,k=!0,y=!1,D=!1,x,N,j=!0,A,E="table",C=!1,B=!1;for(let F=0;F<a.length;F++){let J=a[F];switch(J){case"--samples":d=Number(a[++F]);break;case"--budget":f=Number(a[++F]);break;case"--min-samples":h=Number(a[++F]);break;case"--warmup":g=Number(a[++F]);break;case"--no-interleave":k=!1;break;case"--cpu":y=!0;break;case"--heap":D=!0;break;case"--cpu-interval":x=Number(a[++F]);break;case"--out-dir":N=a[++F];break;case"--no-noise-check":j=!1;break;case"--export-json":A=a[++F];break;case"--format":E=a[++F];break;case"--quiet":C=!0;break;case"--help":case"-h":B=!0;break;default:u.push(J)}}return{commands:u,samples:d,budgetMs:f,minSamples:h,warmup:g,interleave:k,cpu:y,heap:D,cpuIntervalUs:x,outDir:N,noiseCheck:j,exportJson:A,format:E,quiet:C,help:B}}async function he(a){let u=fe(a);if(u.help||u.commands.length===0)return process.stdout.write(me),u.help?0:2;if(!(u.format in s))return process.stderr.write(`Unknown --format "${u.format}". Expected one of: ${Object.keys(s).join(", ")}
234
- `),2;let d;try{d=await R({commands:u.commands,samples:u.samples,budgetMs:u.budgetMs,minSamples:u.minSamples,warmup:u.warmup,interleave:u.interleave,cpu:u.cpu,heap:u.heap,cpuIntervalUs:u.cpuIntervalUs,outDir:u.outDir,noiseCheck:u.noiseCheck})}catch(h){return process.stderr.write(`Run failed: ${h instanceof Error?h.message:String(h)}
235
- `),2}if(u.exportJson)await r(d,u.exportJson);if(!u.quiet){let g=await s[u.format].render(d,{});await L(g)}return d.measurements.some((h)=>h.trials.some((g)=>g.exitCode!==void 0&&g.exitCode!==0))?1:0}function be(a){let u=[],d,f,h,g,k=!1,y=!1,D=!1,x,N=!1,j=[],A=[],E,C=!0,B,F="table",J=!1,V=!1;for(let S=0;S<a.length;S++){let O=a[S];if(O==="--bun-flags"||O.startsWith("--bun-flags=")){let W=O.startsWith("--bun-flags=")?O.slice(12):a[++S]??"";A.push(...W.split(/\s+/).filter(Boolean));continue}switch(O){case"--budget":d=Number(a[++S]);break;case"--samples":f=Number(a[++S]);break;case"--min-samples":h=Number(a[++S]);break;case"--jobs":{let W=a[++S];g=W==="auto"?P():Number(W);break}case"--gc":k=!0;break;case"--cpu":y=!0;break;case"--alloc":D=!0;break;case"--filter":x=a[++S];break;case"--isolate":N=!0;break;case"--preload":j.push(a[++S]);break;case"--out-dir":E=a[++S];break;case"--no-noise-check":C=!1;break;case"--export-json":B=a[++S];break;case"--format":F=a[++S];break;case"--quiet":J=!0;break;case"--help":case"-h":V=!0;break;default:u.push(O)}}return{suites:u,budgetMs:d,samples:f,minSamples:h,jobs:g,gc:k,cpu:y,alloc:D,filter:x,isolate:N,preload:j,bunFlags:A,outDir:E,noiseCheck:C,exportJson:B,format:F,quiet:J,help:V}}async function ge(a){let u=be(a);if(u.help)return process.stdout.write(oe),0;if(!(u.format in s))return process.stderr.write(`Unknown --format "${u.format}". Expected one of: ${Object.keys(s).join(", ")}
236
- `),2;let d=await U(),f=await I(u,d?.bench);if(f.suites.length===0)return process.stdout.write(oe),2;if(f.jobs!==void 0&&!(f.jobs>=1))return process.stderr.write(`--jobs expects a positive integer or "auto".
237
- `),2;let h;try{h=await c(f)}catch(g){return process.stderr.write(`Bench failed: ${g instanceof Error?g.message:String(g)}
238
- `),2}if(u.exportJson)await r(h,u.exportJson);if(!u.quiet){let k=await s[u.format].render(h,{});await L(k)}return 0}function we(a){let u=[],d,f,h="table",g=!1,k=!1;for(let y=0;y<a.length;y++){let D=a[y];switch(D){case"--baseline":d=a[++y];break;case"--export-json":f=a[++y];break;case"--format":h=a[++y];break;case"--quiet":g=!0;break;case"--help":case"-h":k=!0;break;default:u.push(D)}}return{paths:u,baseline:d,exportJson:f,format:h,quiet:g,help:k}}async function ke(a){let u=we(a);if(u.help)return process.stdout.write(ae),0;let d,f;if(u.baseline)d=u.baseline,f=u.paths[0];else d=u.paths[0],f=u.paths[1];if(!d||!f)return process.stdout.write(ae),2;let h,g;try{[h,g]=await Promise.all([t(d),t(f)])}catch(x){return process.stderr.write(`Failed to load documents: ${x instanceof Error?x.message:String(x)}
239
- `),2}let k=b(h,g),y={...g,comparisons:k};if(u.exportJson)await r(y,u.exportJson);if(!u.quiet){if(h.git&&g.git){let j=(A)=>`${A.sha} (${A.branch}${A.dirty?", dirty":""})`;process.stdout.write(`base ${j(h.git)} \u2192 cand ${j(g.git)}
240
- `)}let N=await s[u.format].render(y,{});await L(N)}return k.some((x)=>x.verdict==="fail")?1:0}function ye(a){let u,d="table",f,h,g=!1;for(let k=0;k<a.length;k++){let y=a[k];switch(y){case"--format":d=a[++k]??"";break;case"--measurement":f=a[++k];break;case"--out-dir":h=a[++k];break;case"--help":case"-h":g=!0;break;default:u=y}}return{path:u,format:d,measurementId:f,outDir:h,help:g}}async function ie(a){let u=ye(a);if(u.help||!u.path)return process.stdout.write(de),u.help?0:2;if(!(u.format in s))return process.stderr.write(`Unknown --format "${u.format}". Expected one of: ${Object.keys(s).join(", ")}
241
- `),2;let d;try{d=await t(u.path)}catch(g){return process.stderr.write(`Failed to load ${u.path}: ${g instanceof Error?g.message:String(g)}
242
- `),2}let h=await s[u.format].render(d,{measurementId:u.measurementId});if(!h.text&&(!h.files||h.files.length===0))return process.stderr.write(u.measurementId?`No CPU evidence found for measurement "${u.measurementId}".
246
+ `;function he(u){let a=[],f=[],d,h,k,g,y,E,S=!0,D=!1,T=!1,j,F,P=!0,A,B="table",W=!1,J=!1;for(let x=0;x<u.length;x++){let I=u[x];switch(I){case"--samples":k=Number(u[++x]);break;case"--budget":g=Number(u[++x]);break;case"--min-samples":y=Number(u[++x]);break;case"--warmup":E=Number(u[++x]);break;case"--no-interleave":S=!1;break;case"--prepare":f.push(u[++x]??"");break;case"--time-source":d=u[++x];break;case"--time-unit":h=u[++x];break;case"--cpu":D=!0;break;case"--heap":T=!0;break;case"--cpu-interval":j=Number(u[++x]);break;case"--out-dir":F=u[++x];break;case"--no-noise-check":P=!1;break;case"--export-json":A=u[++x];break;case"--format":B=u[++x];break;case"--quiet":W=!0;break;case"--help":case"-h":J=!0;break;default:a.push(I)}}return{commands:a,prepare:f,timeSource:d,timeUnit:h,samples:k,budgetMs:g,minSamples:y,warmup:E,interleave:S,cpu:D,heap:T,cpuIntervalUs:j,outDir:F,noiseCheck:P,exportJson:A,format:B,quiet:W,help:J}}var ie=["ns","us","ms","s"];async function be(u){let a=he(u);if(a.help||a.commands.length===0)return process.stdout.write(de),a.help?0:2;if(!(a.format in r))return process.stderr.write(`Unknown --format "${a.format}". Expected one of: ${Object.keys(r).join(", ")}
247
+ `),2;if(a.prepare.length>1&&a.prepare.length!==a.commands.length)return process.stderr.write(`--prepare given ${a.prepare.length} times for ${a.commands.length} command(s): give it once (applies to all) or once per command.
248
+ `),2;if(a.timeUnit!==void 0&&!ie.includes(a.timeUnit))return process.stderr.write(`Unknown --time-unit "${a.timeUnit}". Expected one of: ${ie.join(", ")}
249
+ `),2;if(a.timeSource!==void 0)try{new RegExp(a.timeSource)}catch(g){return process.stderr.write(`Invalid --time-source regex: ${g instanceof Error?g.message:String(g)}
250
+ `),2}let f=a.timeSource!==void 0?{pattern:a.timeSource,unit:a.timeUnit}:void 0,d=a.commands.map((g,y)=>({command:g,prepare:a.prepare.length===1?a.prepare[0]:a.prepare[y]})),h;try{h=await C({commands:d,timeSource:f,samples:a.samples,budgetMs:a.budgetMs,minSamples:a.minSamples,warmup:a.warmup,interleave:a.interleave,cpu:a.cpu,heap:a.heap,cpuIntervalUs:a.cpuIntervalUs,outDir:a.outDir,noiseCheck:a.noiseCheck})}catch(g){return process.stderr.write(`Run failed: ${g instanceof Error?g.message:String(g)}
251
+ `),2}if(a.exportJson)await s(h,a.exportJson);if(!a.quiet){let y=await r[a.format].render(h,{});await q(y)}return h.measurements.some((g)=>g.trials.some((y)=>y.exitCode!==void 0&&y.exitCode!==0))?1:0}function ge(u){let a=[],f,d,h,k,g=!1,y=!1,E=!1,S,D=!1,T=[],j=[],F,P=!0,A,B="table",W=!1,J=!1;for(let x=0;x<u.length;x++){let I=u[x];if(I==="--bun-flags"||I.startsWith("--bun-flags=")){let H=I.startsWith("--bun-flags=")?I.slice(12):u[++x]??"";j.push(...H.split(/\s+/).filter(Boolean));continue}switch(I){case"--budget":f=Number(u[++x]);break;case"--samples":d=Number(u[++x]);break;case"--min-samples":h=Number(u[++x]);break;case"--jobs":{let H=u[++x];k=H==="auto"?v():Number(H);break}case"--gc":g=!0;break;case"--cpu":y=!0;break;case"--alloc":E=!0;break;case"--filter":S=u[++x];break;case"--isolate":D=!0;break;case"--preload":T.push(u[++x]);break;case"--out-dir":F=u[++x];break;case"--no-noise-check":P=!1;break;case"--export-json":A=u[++x];break;case"--format":B=u[++x];break;case"--quiet":W=!0;break;case"--help":case"-h":J=!0;break;default:a.push(I)}}return{suites:a,budgetMs:f,samples:d,minSamples:h,jobs:k,gc:g,cpu:y,alloc:E,filter:S,isolate:D,preload:T,bunFlags:j,outDir:F,noiseCheck:P,exportJson:A,format:B,quiet:W,help:J}}async function we(u){let a=ge(u);if(a.help)return process.stdout.write(oe),0;if(!(a.format in r))return process.stderr.write(`Unknown --format "${a.format}". Expected one of: ${Object.keys(r).join(", ")}
252
+ `),2;let f=await O(),d=await N(a,f?.bench);if(d.suites.length===0)return process.stdout.write(oe),2;if(d.jobs!==void 0&&!(d.jobs>=1))return process.stderr.write(`--jobs expects a positive integer or "auto".
253
+ `),2;let h;try{h=await c(d)}catch(k){return process.stderr.write(`Bench failed: ${k instanceof Error?k.message:String(k)}
254
+ `),2}if(a.exportJson)await s(h,a.exportJson);if(!a.quiet){let g=await r[a.format].render(h,{});await q(g)}return 0}function ke(u){let a=[],f,d,h="table",k=!1,g=!1;for(let y=0;y<u.length;y++){let E=u[y];switch(E){case"--baseline":f=u[++y];break;case"--export-json":d=u[++y];break;case"--format":h=u[++y];break;case"--quiet":k=!0;break;case"--help":case"-h":g=!0;break;default:a.push(E)}}return{paths:a,baseline:f,exportJson:d,format:h,quiet:k,help:g}}async function ye(u){let a=ke(u);if(a.help)return process.stdout.write(ae),0;let f,d;if(a.baseline)f=a.baseline,d=a.paths[0];else f=a.paths[0],d=a.paths[1];if(!f||!d)return process.stdout.write(ae),2;let h,k;try{[h,k]=await Promise.all([t(f),t(d)])}catch(S){return process.stderr.write(`Failed to load documents: ${S instanceof Error?S.message:String(S)}
255
+ `),2}let g=b(h,k),y={...k,comparisons:g};if(a.exportJson)await s(y,a.exportJson);if(!a.quiet){if(h.git&&k.git){let T=(j)=>`${j.sha} (${j.branch}${j.dirty?", dirty":""})`;process.stdout.write(`base ${T(h.git)} \u2192 cand ${T(k.git)}
256
+ `)}let D=await r[a.format].render(y,{});await q(D)}return g.some((S)=>S.verdict==="fail")?1:0}function xe(u){let a,f="table",d,h,k=!1;for(let g=0;g<u.length;g++){let y=u[g];switch(y){case"--format":f=u[++g]??"";break;case"--measurement":d=u[++g];break;case"--out-dir":h=u[++g];break;case"--help":case"-h":k=!0;break;default:a=y}}return{path:a,format:f,measurementId:d,outDir:h,help:k}}async function le(u){let a=xe(u);if(a.help||!a.path)return process.stdout.write(pe),a.help?0:2;if(!(a.format in r))return process.stderr.write(`Unknown --format "${a.format}". Expected one of: ${Object.keys(r).join(", ")}
257
+ `),2;let f;try{f=await t(a.path)}catch(k){return process.stderr.write(`Failed to load ${a.path}: ${k instanceof Error?k.message:String(k)}
258
+ `),2}let h=await r[a.format].render(f,{measurementId:a.measurementId});if(!h.text&&(!h.files||h.files.length===0))return process.stderr.write(a.measurementId?`No CPU evidence found for measurement "${a.measurementId}".
243
259
  `:`No CPU evidence found in this document (no cpu-phase measurements). Capture some with "ostia time --cpu ...".
244
- `),2;return await L(h,u.outDir),0}function Ce(a){let u=!1,d,f=!1,h,g=!1,k=!1;for(let y=0;y<a.length;y++)switch(a[y]){case"--full":u=!0;break;case"--baseline":d=a[++y];break;case"--save-baseline":f=!0;break;case"--export-json":h=a[++y];break;case"--quiet":g=!0;break;case"--help":case"-h":k=!0;break}return{full:u,baseline:d,saveBaseline:f,exportJson:h,quiet:g,help:k}}async function xe(a){let u=Ce(a);if(u.help)return process.stdout.write(pe),0;let d=await U();if(!d)return process.stderr.write(`No ostia.config.json found. "ostia ci" needs configured workloads.
245
- `),2;if(d.workloads.length===0)return process.stderr.write(`ostia.config.json has no "workloads" configured.
246
- `),2;let f;try{f=await te({config:d,full:u.full,baselineName:u.baseline})}catch(h){if(h instanceof H)return process.stderr.write(`${h.message}
260
+ `),2;return await q(h,a.outDir),0}function Ce(u){let a=!1,f,d=!1,h,k=!1,g=!1;for(let y=0;y<u.length;y++)switch(u[y]){case"--full":a=!0;break;case"--baseline":f=u[++y];break;case"--save-baseline":d=!0;break;case"--export-json":h=u[++y];break;case"--quiet":k=!0;break;case"--help":case"-h":g=!0;break}return{full:a,baseline:f,saveBaseline:d,exportJson:h,quiet:k,help:g}}async function Pe(u){let a=Ce(u);if(a.help)return process.stdout.write(fe),0;let f=await O();if(!f)return process.stderr.write(`No ostia.config.json found. "ostia ci" needs configured workloads.
261
+ `),2;if(f.workloads.length===0)return process.stderr.write(`ostia.config.json has no "workloads" configured.
262
+ `),2;let d;try{d=await te({config:f,full:a.full,baselineName:a.baseline})}catch(h){if(h instanceof L)return process.stderr.write(`${h.message}
247
263
  `),2;return process.stderr.write(`CI run failed: ${h instanceof Error?h.message:String(h)}
248
- `),2}if(u.exportJson)await r(f.document,u.exportJson);if(u.saveBaseline&&f.summary.regressed===0)await r(f.document,M(d,u.baseline));if(!u.quiet)process.stdout.write(se(f.summary));return f.summary.regressed>0?1:0}async function Pe(a){if(a.includes("--help")||a.includes("-h"))return process.stdout.write(q),0;let u=a[0],d=await U();if(!d)return process.stderr.write(`No ostia.config.json found. "ostia baseline save" needs configured workloads.
249
- `),2;if(d.workloads.length===0)return process.stderr.write(`ostia.config.json has no "workloads" configured.
250
- `),2;let f=await ne(d,u);return process.stdout.write(`Wrote ${f}
251
- `),0}async function je(a){if(a.includes("--help")||a.includes("-h"))return process.stdout.write(q),0;let u=await U();if(!u)return process.stderr.write(`No ostia.config.json found.
252
- `),2;let d=await re(u);if(d.length===0)return process.stdout.write(`No baselines found in ${u.baselineDir}.
253
- `),0;for(let f of d){let h=f.git?` ${f.git.sha} (${f.git.branch}${f.git.dirty?", dirty":""})`:"";process.stdout.write(`${f.name} ${f.workloads} workloads created ${f.createdAt} toolVersion ${f.toolVersion}${h}
254
- `)}return 0}async function ve(a){let[u,...d]=a;if(!u||u==="--help"||u==="-h")return process.stdout.write(q),u?0:2;let f=await U();if(!f)return process.stderr.write(`No ostia.config.json found.
255
- `),2;return ie([M(f,u),...d])}async function De(a){let[u,...d]=a;switch(u){case"save":return Pe(d);case"list":return je(d);case"show":return ve(d);case void 0:case"--help":case"-h":return process.stdout.write(q),u===void 0?2:0;default:return process.stderr.write(`Unknown "ostia baseline ${u}". Run "ostia baseline --help".
256
- `),2}}async function $e(){let[a,...u]=process.argv.slice(2);switch(a){case"time":return he(u);case"bench":return ge(u);case"compare":return ke(u);case"report":return ie(u);case"ci":return xe(u);case"baseline":return De(u);case void 0:case"--help":case"-h":return process.stdout.write(`ostia - Bun-native profile IR engine
264
+ `),2}if(a.exportJson)await s(d.document,a.exportJson);if(a.saveBaseline&&d.summary.regressed===0)await s(d.document,U(f,a.baseline));if(!a.quiet)process.stdout.write(se(d.summary));return d.summary.regressed>0?1:0}async function je(u){if(u.includes("--help")||u.includes("-h"))return process.stdout.write(_),0;let a=u[0],f=await O();if(!f)return process.stderr.write(`No ostia.config.json found. "ostia baseline save" needs configured workloads.
265
+ `),2;if(f.workloads.length===0)return process.stderr.write(`ostia.config.json has no "workloads" configured.
266
+ `),2;let d=await ne(f,a);return process.stdout.write(`Wrote ${d}
267
+ `),0}async function ve(u){if(u.includes("--help")||u.includes("-h"))return process.stdout.write(_),0;let a=await O();if(!a)return process.stderr.write(`No ostia.config.json found.
268
+ `),2;let f=await re(a);if(f.length===0)return process.stdout.write(`No baselines found in ${a.baselineDir}.
269
+ `),0;for(let d of f){let h=d.git?` ${d.git.sha} (${d.git.branch}${d.git.dirty?", dirty":""})`:"";process.stdout.write(`${d.name} ${d.workloads} workloads created ${d.createdAt} toolVersion ${d.toolVersion}${h}
270
+ `)}return 0}async function $e(u){let[a,...f]=u;if(!a||a==="--help"||a==="-h")return process.stdout.write(_),a?0:2;let d=await O();if(!d)return process.stderr.write(`No ostia.config.json found.
271
+ `),2;return le([U(d,a),...f])}async function Se(u){let[a,...f]=u;switch(a){case"save":return je(f);case"list":return ve(f);case"show":return $e(f);case void 0:case"--help":case"-h":return process.stdout.write(_),a===void 0?2:0;default:return process.stderr.write(`Unknown "ostia baseline ${a}". Run "ostia baseline --help".
272
+ `),2}}async function De(){let[u,...a]=process.argv.slice(2);switch(u){case"time":return be(a);case"bench":return we(a);case"compare":return ye(a);case"report":return le(a);case"ci":return Pe(a);case"baseline":return Se(a);case void 0:case"--help":case"-h":return process.stdout.write(`ostia - Bun-native profile IR engine
257
273
 
258
274
  Commands:
259
275
  time Time commands N times and report timing/CPU/heap
@@ -264,5 +280,5 @@ Commands:
264
280
  baseline Manage baseline ProfileDocuments (save/list/show)
265
281
 
266
282
  Run "ostia <command> --help" for details.
267
- `),a===void 0?2:0;default:return process.stderr.write(`Unknown subcommand "${a}". Run "ostia --help".
268
- `),2}}if(import.meta.main)$e().then((a)=>process.exit(a));
283
+ `),u===void 0?2:0;default:return process.stderr.write(`Unknown subcommand "${u}". Run "ostia --help".
284
+ `),2}}if(import.meta.main)De().then((u)=>process.exit(u));
package/index.d.ts CHANGED
@@ -1,7 +1,27 @@
1
1
  export declare function defineConfig(config: Partial<OstiaConfig>): Partial<OstiaConfig>;
2
2
 
3
- interface TimeOptions {
4
- commands: (string | string[])[];
3
+ export interface CommandSpec {
4
+ command: string | string[];
5
+ label?: string;
6
+ /** Overrides `TimeOptions.prepare` for this command. */
7
+ prepare?: PrepareHook;
8
+ /** Overrides `TimeOptions.timeSource` for this command. */
9
+ timeSource?: TimeSource;
10
+ }
11
+
12
+ export interface TimeOptions {
13
+ commands: (string | string[] | CommandSpec)[];
14
+ /** Runs before every trial of every command (warmup and instrumented
15
+ * trials included), unmeasured, in `cwd`/`env`: a command string / argv
16
+ * array spawned and awaited, or a function. hyperfine's `--prepare`. A
17
+ * `CommandSpec.prepare` overrides it per command. */
18
+ prepare?: PrepareHook;
19
+ /** Take every command's timing from a number in its own output instead of
20
+ * its wall clock (e.g. a build tool's `built in 342ms` line, which
21
+ * excludes runtime startup). A `CommandSpec.timeSource` overrides it per
22
+ * command. The parsed value becomes `timing.samples`; each trial keeps
23
+ * `wallNs` too. */
24
+ timeSource?: TimeSource;
5
25
  /** Exact trial count. When set, `budgetMs` is ignored. */
6
26
  samples?: number;
7
27
  /** Wall-clock time budget for the sampling loop, ms (default: a
@@ -46,11 +66,20 @@ interface ProfileResult<T> {
46
66
 
47
67
  export declare function profile<T>(fn: () => T | Promise<T>, opts?: ProfileOptions): Promise<ProfileResult<T>>;
48
68
 
49
- interface WorkloadConfig {
69
+ export interface WorkloadConfig {
50
70
  label?: string;
51
71
  command?: string[];
52
72
  suites?: string[];
53
73
  inputs?: string[];
74
+ /** `command` only. Runs before every trial (warmup included), unmeasured:
75
+ * a command string / argv array in both `.ts` and JSON config, or a
76
+ * function in `ostia.config.ts`. A function-form hook makes the workload
77
+ * uncacheable for `ostia ci` (its effect can't be fingerprinted), so it
78
+ * always executes. */
79
+ prepare?: PrepareHook;
80
+ /** `command` only. Take timing from a number in the command's own output
81
+ * instead of its wall clock; see `TimeSource`. */
82
+ timeSource?: TimeSource;
54
83
  }
55
84
 
56
85
  interface BenchConfig {
@@ -152,6 +181,22 @@ export interface Workload {
152
181
  label?: string;
153
182
  command?: string[];
154
183
  shell?: string;
184
+ /** Command form of the `prepare` hook that ran before every trial of this
185
+ * command (`ostia time --prepare`, `time({ prepare })`, config `prepare`).
186
+ * Part of the workload id: the same command with and without a prepare
187
+ * step measures different things. A function-form hook isn't
188
+ * serializable and is omitted here (its source text is still hashed into
189
+ * the id). */
190
+ prepare?: string[];
191
+ /** Where this command's timing samples came from when not the subprocess
192
+ * wall clock: a regex over the command's own output and the unit of the
193
+ * number it captures. Part of the workload id, so the same command timed
194
+ * by wall clock and by its own report are two workloads. */
195
+ timeSource?: {
196
+ pattern: string;
197
+ group?: number;
198
+ unit?: "ns" | "us" | "ms" | "s";
199
+ };
155
200
  /** `task` is the "group/name" id the bench registry assigns; `group` is the
156
201
  * enclosing `group()` name when there is one. Renderers prefer `group` over
157
202
  * splitting `task` on "/", so task names may contain slashes. */
@@ -219,6 +264,10 @@ interface Measurement {
219
264
  interface Trial {
220
265
  i: number;
221
266
  wallNs: number;
267
+ /** The command's self-reported time (ns) when the workload has a
268
+ * `timeSource`; `timing.samples` are these, not `wallNs`, in that case.
269
+ * `wallNs` stays alongside so a document keeps both. */
270
+ reportedNs?: number;
222
271
  exitCode?: number;
223
272
  userNs?: number;
224
273
  systemNs?: number;
@@ -394,6 +443,23 @@ interface Comparison {
394
443
  verdict: "pass" | "fail";
395
444
  }
396
445
 
446
+ export interface PrepareRun {
447
+ phase: "warmup" | "timing" | "cpu" | "heap";
448
+ index: number;
449
+ }
450
+
451
+ export type PrepareFn = (run: PrepareRun) => unknown;
452
+
453
+ export type PrepareHook = string | string[] | PrepareFn;
454
+
455
+ export type TimeUnit = "ns" | "us" | "ms" | "s";
456
+
457
+ export interface TimeSource {
458
+ pattern: string | RegExp;
459
+ group?: number;
460
+ unit?: TimeUnit;
461
+ }
462
+
397
463
  export declare function keep(value: unknown): void;
398
464
 
399
465
  interface BenchOptions {
package/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{c,b,_,L,s,H,R,J}from"./chunk-r5b8vf8w.js";import{n,r,t,x,V,G}from"./chunk-qbt85kmg.js";export{c as bench,b as compareDocuments,n as createDocument,H as defineConfig,V as group,x as keep,t as loadDocument,J as profile,_ as range,s as renderers,r as saveDocument,L as sweep,G as task,R as time};
2
+ import{c,b,J,V,r,G,C,z}from"./chunk-h6579788.js";import{n,s,t,T,q,K}from"./chunk-9dqf5cxf.js";export{c as bench,b as compareDocuments,n as createDocument,G as defineConfig,q as group,T as keep,t as loadDocument,z as profile,J as range,r as renderers,s as saveDocument,V as sweep,K as task,C as time};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ostia",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Fast profiling and benchmarking for Bun.",
5
5
  "type": "module",
6
6
  "exports": {
package/runner.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{n,N,i,a,o,r,d,f,g,F,O,B,h,C,U,W,A,j}from"./chunk-qbt85kmg.js";import{heapStats as X}from"bun:jsc";var Y=100;function z(){try{return X().heapSize}catch{return process.memoryUsage().heapUsed}}async function Z(l,m=Y){let w=Bun.nanoseconds();Bun.gc(!0);let t=z();for(let u=0;u<m;u++){let p=l();if(p instanceof Promise)await p}Bun.gc(!0);let k=z(),c=Bun.nanoseconds()-w;return{memory:{origin:"heapStats",bytesPerOp:Math.max(0,(k-t)/m)},diagnosticWallNs:c}}var ee=200,te=20;async function q(l,m=ee){let w=m*1e6,t=async()=>{let p=Bun.nanoseconds();while(Bun.nanoseconds()-p<w){let b=l();if(b instanceof Promise)await b}},{cpu:k,jit:c,diagnosticWallNs:u}=await d(t);return{cpu:k,jit:c,diagnosticWallNs:u}}function K(l){let{llint:m,baseline:w,dfg:t,ftl:k}=l.tiers,c=m+w+t+k;if(c===0)return;let u=m/c*100,p=w/c*100,b=t/c*100,x=k/c*100;if(u+p<=te)return;return{code:"jit-cold",message:`${(u+p).toFixed(1)}% of CPU samples were in the llint/baseline tiers: the JIT never warmed this task up.`,data:{llintPct:u,baselinePct:p,dfgPct:b,ftlPct:x}}}async function ne(){let[l,m,w]=process.argv.slice(2);if(!l||!m)return process.stderr.write(`bench runner: usage: runner.ts <suiteFile> <outputPath> [optsJson]
4
- `),2;let t=w?JSON.parse(w):{};for(let s of t.preload??[])await import(s);B(),await import(l);let k=O();if(k.length===0)return process.stderr.write(`bench runner: ${l} registered no tasks (no task() calls found).
5
- `),2;let c=k.filter((s)=>s.only),u=c.length>0?c:k;if(c.length>0)process.stderr.write(`bench: ${c.length} task(s) selected by .only
6
- `);let p=j(u,t.filter);if(t.taskIds){let s=new Set(t.taskIds);p=p.filter((e)=>s.has(h(e)))}if(p.length===0)return process.stderr.write(`bench runner: --filter ${JSON.stringify(t.filter)} matched zero of ${u.length} registered task(s) in ${l}.
7
- `),2;if(t.planPath){let s=p.map((e)=>({id:h(e),isolate:C(e,t.isolate??!1)}));await Bun.write(t.planPath,JSON.stringify({tasks:s}))}let b=t.taskIds?p:p.filter((s)=>!C(s,t.isolate??!1)),S=b.some((s)=>!s.skipped)&&t.noiseCheck!==!1?f():void 0,R=S?g(S):void 0,v=new Map,E=new Map;b.forEach((s,e)=>{if(s.groupName===void 0||s.skipped)return;if(!v.has(s.groupName))v.set(s.groupName,e);E.set(s.groupName,e)});let J=[],P=[];for(let s=0;s<b.length;s++){let e=b[s],D=h(e),I=N(l,D,{label:D,baseline:e.baseline,group:e.groupName,description:e.opts?.description,groupDescription:e.groupDescription,isolated:t.markIsolated,params:e.params,skipped:e.skipped});if(J.push(I),e.skipped)continue;let Q=e.groupName!==void 0&&v.get(e.groupName)===s,V=e.groupName!==void 0&&E.get(e.groupName)===s;if(Q&&e.groupBefore)await e.groupBefore();if(e.opts?.before)await e.opts.before();let _=e.opts?.budgetMs??t.budgetMs,L=e.opts?.samples??t.samples,H=e.opts?.minSamples??t.minSamples,T={...t,..._!==void 0&&{budgetMs:_},...L!==void 0&&{samples:L},...H!==void 0&&{minSamples:H},gc:U(e,t.gc??!1)},M=await F(e.fn,T);if(P.push(i({workload:I,configFingerprint:o({budgetMs:T.budgetMs??null,samples:T.samples??null,minSamples:T.minSamples??null,gc:T.gc??!1}),trials:M.trials,timing:M.timing,warnings:R&&P.length===0?[...M.warnings,R]:M.warnings})),W(e,t.cpu??!1)){let y=await q(e.fn),G=K(y.jit);P.push(a({workload:I,phase:"cpu",configFingerprint:o({cpu:!0}),diagnosticWallNs:y.diagnosticWallNs,cpu:y.cpu,jit:y.jit,warnings:G?[G]:[],artifacts:[]}))}if(A(e,t.alloc??!1)){let y=await Z(e.fn);P.push(a({workload:I,phase:"memstats",configFingerprint:o({alloc:!0}),diagnosticWallNs:y.diagnosticWallNs,memory:y.memory,warnings:[],artifacts:[]}))}if(e.opts?.after)await e.opts.after();if(V&&e.groupAfter)await e.groupAfter()}return await r(n(J,P,S),m),0}ne().then((l)=>process.exit(l));
3
+ import{n,O,i,a,o,s,d,f,g,U,B,A,h,I,j,_,L,H}from"./chunk-9dqf5cxf.js";import{heapStats as X}from"bun:jsc";var Y=100;function z(){try{return X().heapSize}catch{return process.memoryUsage().heapUsed}}async function Z(l,m=Y){let w=Bun.nanoseconds();Bun.gc(!0);let t=z();for(let u=0;u<m;u++){let p=l();if(p instanceof Promise)await p}Bun.gc(!0);let k=z(),c=Bun.nanoseconds()-w;return{memory:{origin:"heapStats",bytesPerOp:Math.max(0,(k-t)/m)},diagnosticWallNs:c}}var ee=200,te=20;async function q(l,m=ee){let w=m*1e6,t=async()=>{let p=Bun.nanoseconds();while(Bun.nanoseconds()-p<w){let b=l();if(b instanceof Promise)await b}},{cpu:k,jit:c,diagnosticWallNs:u}=await d(t);return{cpu:k,jit:c,diagnosticWallNs:u}}function K(l){let{llint:m,baseline:w,dfg:t,ftl:k}=l.tiers,c=m+w+t+k;if(c===0)return;let u=m/c*100,p=w/c*100,b=t/c*100,S=k/c*100;if(u+p<=te)return;return{code:"jit-cold",message:`${(u+p).toFixed(1)}% of CPU samples were in the llint/baseline tiers: the JIT never warmed this task up.`,data:{llintPct:u,baselinePct:p,dfgPct:b,ftlPct:S}}}async function ne(){let[l,m,w]=process.argv.slice(2);if(!l||!m)return process.stderr.write(`bench runner: usage: runner.ts <suiteFile> <outputPath> [optsJson]
4
+ `),2;let t=w?JSON.parse(w):{};for(let r of t.preload??[])await import(r);A(),await import(l);let k=B();if(k.length===0)return process.stderr.write(`bench runner: ${l} registered no tasks (no task() calls found).
5
+ `),2;let c=k.filter((r)=>r.only),u=c.length>0?c:k;if(c.length>0)process.stderr.write(`bench: ${c.length} task(s) selected by .only
6
+ `);let p=H(u,t.filter);if(t.taskIds){let r=new Set(t.taskIds);p=p.filter((e)=>r.has(h(e)))}if(p.length===0)return process.stderr.write(`bench runner: --filter ${JSON.stringify(t.filter)} matched zero of ${u.length} registered task(s) in ${l}.
7
+ `),2;if(t.planPath){let r=p.map((e)=>({id:h(e),isolate:I(e,t.isolate??!1)}));await Bun.write(t.planPath,JSON.stringify({tasks:r}))}let b=t.taskIds?p:p.filter((r)=>!I(r,t.isolate??!1)),M=b.some((r)=>!r.skipped)&&t.noiseCheck!==!1?f():void 0,v=M?g(M):void 0,W=new Map,x=new Map;b.forEach((r,e)=>{if(r.groupName===void 0||r.skipped)return;if(!W.has(r.groupName))W.set(r.groupName,e);x.set(r.groupName,e)});let F=[],P=[];for(let r=0;r<b.length;r++){let e=b[r],R=h(e),T=O(l,R,{label:R,baseline:e.baseline,group:e.groupName,description:e.opts?.description,groupDescription:e.groupDescription,isolated:t.markIsolated,params:e.params,skipped:e.skipped});if(F.push(T),e.skipped)continue;let Q=e.groupName!==void 0&&W.get(e.groupName)===r,V=e.groupName!==void 0&&x.get(e.groupName)===r;if(Q&&e.groupBefore)await e.groupBefore();if(e.opts?.before)await e.opts.before();let E=e.opts?.budgetMs??t.budgetMs,J=e.opts?.samples??t.samples,D=e.opts?.minSamples??t.minSamples,N={...t,...E!==void 0&&{budgetMs:E},...J!==void 0&&{samples:J},...D!==void 0&&{minSamples:D},gc:j(e,t.gc??!1)},C=await U(e.fn,N);if(P.push(i({workload:T,configFingerprint:o({budgetMs:N.budgetMs??null,samples:N.samples??null,minSamples:N.minSamples??null,gc:N.gc??!1}),trials:C.trials,timing:C.timing,warnings:v&&P.length===0?[...C.warnings,v]:C.warnings})),_(e,t.cpu??!1)){let y=await q(e.fn),G=K(y.jit);P.push(a({workload:T,phase:"cpu",configFingerprint:o({cpu:!0}),diagnosticWallNs:y.diagnosticWallNs,cpu:y.cpu,jit:y.jit,warnings:G?[G]:[],artifacts:[]}))}if(L(e,t.alloc??!1)){let y=await Z(e.fn);P.push(a({workload:T,phase:"memstats",configFingerprint:o({alloc:!0}),diagnosticWallNs:y.diagnosticWallNs,memory:y.memory,warnings:[],artifacts:[]}))}if(e.opts?.after)await e.opts.after();if(V&&e.groupAfter)await e.groupAfter()}return await s(n(F,P,M),m),0}ne().then((l)=>process.exit(l));
package/chunk-qbt85kmg.js DELETED
@@ -1,4 +0,0 @@
1
- // @bun
2
- function k(s){return JSON.stringify(me(s))}function me(s){if(Array.isArray(s))return s.map(me);if(s!==null&&typeof s==="object"){let c={};for(let l of Object.keys(s).sort())c[l]=me(s[l]);return c}return s}function e(s,...c){let l=Bun.CryptoHasher.hash("sha256",k(c),"hex");return`${s}_${l.slice(0,16)}`}var pe,Te=!1;function ge(s){let c=Bun.spawnSync(["git",...s],{timeout:200,stdout:"pipe",stderr:"ignore"});return c.success?c.stdout.toString().trim():void 0}function ye(){if(Te)return pe;Te=!0;try{let s=ge(["rev-parse","--short","HEAD"]);if(s===void 0)pe=void 0;else{let c=ge(["rev-parse","--abbrev-ref","HEAD"]),l=ge(["status","--porcelain"]);pe={sha:s,branch:c??"HEAD",dirty:(l?.length??0)>0}}}catch{pe=void 0}return pe}var m="0.1.0";function n(s,c,l){let w=ye();return{schemaVersion:2,toolVersion:m,bunVersion:Bun.version,platform:{os:process.platform,arch:process.arch},createdAt:new Date().toISOString(),workloads:s,measurements:c,...l!==void 0&&{environment:l},...w!==void 0&&{git:w}}}function p(s,c){return{id:e("wl","subprocess",s,process.cwd()),kind:"subprocess",command:s,label:c}}function D(s,c){return{id:e("wl","inprocess",s.name,s.toString()),kind:"inprocess",label:c}}function N(s,c,l={}){return{id:l.params!==void 0?e("wl","inprocess-entry",s,c,l.params):e("wl","inprocess-entry",s,c),kind:"inprocess",entry:{file:s,task:c,...l.group!==void 0&&{group:l.group}},...l.label!==void 0&&{label:l.label},...l.baseline!==void 0&&{baseline:l.baseline},...l.description!==void 0&&{description:l.description},...l.groupDescription!==void 0&&{groupDescription:l.groupDescription},...l.isolated!==void 0&&{isolated:l.isolated},...l.params!==void 0&&{params:l.params},...l.skipped!==void 0&&{skipped:l.skipped}}}function i(s){return{id:e("run",s.workload.id,"timing",s.configFingerprint,Bun.version,m),workloadId:s.workload.id,phase:"timing",instrumented:!1,configFingerprint:s.configFingerprint,trials:s.trials,timing:s.timing,warnings:s.warnings,artifacts:[],memory:Ne(s.trials),...s.interleaved!==void 0&&{interleaved:s.interleaved}}}function Ne(s){let c=s.map((l)=>l.maxRssBytes).filter((l)=>l!==void 0);if(c.length===0)return;return{origin:"resourceUsage",perTrial:s.map((l)=>({rssBytes:l.maxRssBytes})),maxRssBytes:Math.max(...c)}}function a(s){return{id:e("run",s.workload.id,s.phase,s.configFingerprint,Bun.version,m),workloadId:s.workload.id,phase:s.phase,instrumented:!0,configFingerprint:s.configFingerprint,trials:[{i:0,wallNs:s.diagnosticWallNs,exitCode:s.exitCode}],diagnosticWallNs:s.diagnosticWallNs,cpu:s.cpu,heap:s.heap,memory:s.memory,jit:s.jit,warnings:s.warnings,artifacts:s.artifacts}}async function S(s,c,l){let v=await Bun.file(l).arrayBuffer(),R=new Bun.CryptoHasher("sha256");return R.update(v),{id:e("art",s,c,l),kind:c,path:l,sha256:R.digest("hex"),bytes:v.byteLength}}function o(s){return e("cfg",s)}function M(s){return`${JSON.stringify(me(s),null,2)}
3
- `}async function r(s,c){await Bun.write(c,M(s))}function Oe(s){if(s.schemaVersion===2)return s;let{runs:c,comparisons:l,...w}=s;return{...w,schemaVersion:2,measurements:c.map(({baselineRunId:v,...R})=>({...R,...v!==void 0&&{baselineMeasurementId:v}})),...l!==void 0&&{comparisons:l.map(({baselineRunId:v,candidateRunId:R,...I})=>({...I,baselineMeasurementId:v,candidateMeasurementId:R}))}}}async function t(s){let c=await Bun.file(s).text(),l=JSON.parse(c);return Oe(l)}import{profile as Pe}from"bun:jsc";var Ae=new Map([["LLInt","llint"],["Baseline","baseline"],["DFG","dfg"],["FTL","ftl"]]),xe=4294967295;function Me(s,c){let l=c??s.interval*1e6,w=new Map,v=[];function R(b,T,P,Z){let Q=w.get(b);if(Q===void 0)Q=new Map,w.set(b,Q);let X=T??"",te=Q.get(X);if(te===void 0)te=v.length,Q.set(X,te),v.push({key:e("fr",b,X),name:b,url:T,line:P,col:Z});return te}function I(b){let T=b.line===xe,P=T?void 0:b.line-1,Z=T||b.column===xe?void 0:b.column-1;return R(b.name,b.sourceURL,P,Z)}let J=R("(root)",void 0,void 0,void 0),_=1,q={id:0,frameIx:J,children:new Map,selfUs:0,samples:0,totalUs:0},ne=new Map([[0,q]]),Y={llint:0,baseline:0,dfg:0,ftl:0},H=new Map,ue=[],oe=[];for(let b of s.traces){let T=b.frames,P=q;for(let X=T.length-1;X>=0;X--){let te=I(T[X]),le=P.children.get(te);if(!le)le={id:_++,frameIx:te,children:new Map,selfUs:0,samples:0,totalUs:0},P.children.set(te,le),ne.set(le.id,le);P=le}P.selfUs+=l,P.samples+=1,ue.push(P.id),oe.push(l);let Z=T[0],Q=Z&&Ae.get(Z.category);if(Q){Y[Q]++;let X=H.get(Q)??new Map;X.set(P.frameIx,(X.get(P.frameIx)??0)+1),H.set(Q,X)}}function ee(b){let T=b.selfUs;for(let P of b.children.values())T+=ee(P);return b.totalUs=T,T}ee(q);let se=new Map;function re(b){let T=se.get(b.frameIx);if(T)T.selfUs+=b.selfUs,T.totalUs+=b.totalUs,T.samples+=b.samples;else se.set(b.frameIx,{frameIx:b.frameIx,selfUs:b.selfUs,totalUs:b.totalUs,samples:b.samples});for(let P of b.children.values())re(P)}re(q);let ie=[...ne.values()].map((b)=>({id:b.id,frameIx:b.frameIx,children:[...b.children.values()].map((T)=>T.id)})),ae={origin:"jsc-profile",samplingIntervalUs:l,frames:v,nodes:ie,totals:[...se.values()].sort((b,T)=>T.selfUs-b.selfUs),samples:{nodeIds:ue,timeDeltasUs:oe}},L=[...H.entries()].flatMap(([b,T])=>[...T.entries()].sort((P,Z)=>Z[1]-P[1]).slice(0,3).map(([P,Z])=>({tier:b,frameKey:v[P].key,samples:Z})));return{cpu:ae,jit:{origin:"jsc-profile",tiers:Y,topFramesByTier:L}}}var Ue=1000;async function d(s,c={}){let l=c.intervalUs??Ue,w,v=Bun.nanoseconds(),R=await Pe(async()=>(w=await s(),w),l),I=Bun.nanoseconds()-v,{cpu:J,jit:_}=Me(R.stackTraces,l);return{result:w,cpu:J,jit:_,diagnosticWallNs:I}}import be from"os";function u(s){if(s.length===0)throw Error("computeTimingStats: samples must be non-empty");let c=s.length,l=ve(s),w=0;for(let b=0;b<c;b++)w+=s[b];let v=w/c,R=ce(l,0.5),I=0;for(let b=0;b<c;b++){let T=s[b]-v;I+=T*T}let J=Math.sqrt(I/c),_=l[0],q=l[c-1],ne=ce(l,0.25),Y=ce(l,0.75),H=Y-ne,ue=ne-1.5*H,oe=Y+1.5*H,ee=ne-3*H,se=Y+3*H,re=0,ie=0;for(let b=0;b<c;b++){let T=s[b];if(T<ee||T>se)ie++;else if(T<ue||T>oe)re++}let ae=ce(l,0.99),L=new Float64Array(c);for(let b=0;b<c;b++)L[b]=Math.abs(s[b]-R);L.sort();let K=ce(L,0.5);return{unit:"ns",samples:s,mean:v,median:R,stddev:J,min:_,max:q,outliers:{mild:re,severe:ie},p75:Y,p99:ae,mad:K}}function ve(s){let c=new Float64Array(s.length);return c.set(s),c.sort(),c}function ce(s,c){let l=s.length;if(l===1)return s[0];let w=c*(l-1),v=Math.floor(w),R=Math.ceil(w);if(v===R)return s[v];let I=w-v;return s[v]*(1-I)+s[R]*I}var De=5000000,_e=200;function y(s,c,l="subprocess"){let w=[],v=s.samples[0];if(v!==void 0){let I=ve(s.samples),J=ce(I,0.25),q=ce(I,0.75)-J;if(v>s.median+3*q&&q>0)w.push({code:"slow-first-run",message:`First run took ${(v/1e6).toFixed(2)}ms, much slower than the median ${(s.median/1e6).toFixed(2)}ms. Consider more warmup.`,data:{firstNs:v,medianNs:s.median}})}if(s.outliers.mild+s.outliers.severe>0)w.push({code:"outliers-detected",message:`${s.outliers.mild+s.outliers.severe} outlier(s) detected (${s.outliers.severe} severe, ${s.outliers.mild} mild).`,data:s.outliers});if(l==="subprocess"&&s.median<De)w.push({code:"fast-command",message:`Median run time (${(s.median/1e6).toFixed(3)}ms) is very fast; results may be dominated by spawn overhead.`,data:{medianNs:s.median}});if(l==="inprocess"&&s.median<_e)w.push({code:"below-timer-resolution",message:`Median run time (${s.median.toFixed(0)}ns) is close to timer resolution; consider a larger batch size or a coarser operation.`,data:{medianNs:s.median}});let R=c.filter((I)=>I!==void 0&&I!==0);if(R.length>0)w.push({code:"nonzero-exit",message:`${R.length} of ${c.length} trial(s) exited non-zero.`,data:{exitCodes:R}});return w}var Ce=200,Re=64,We=(()=>{let s=new Uint8Array(4096);for(let c=0;c<s.length;c++)s[c]=c*2654435761&255;return s})();function Ge(s,c){let l=c;for(let w=0;w<s.length;w++)l^=s[w],l=Math.imul(l,16777619);return l>>>0}function Le(s){let c=u(s),l=c.mad??0;return{floorPct:c.median===0?0:l/c.median*100,referenceMedianNs:c.median,samples:s.length}}function Ie(s=Ce){let c=s*1e6,l=[],w=0,v=Bun.nanoseconds(),R=0;while(R<c){let I=Bun.nanoseconds();for(let _=0;_<Re;_++)w^=Ge(We,_);let J=Bun.nanoseconds();l.push((J-I)/Re),R=Bun.nanoseconds()-v}return Le(l)}var Je=0.75;function f(){let[s=0,c=0]=be.loadavg();return{cpuModel:be.cpus()[0]?.model??"unknown",cores:be.availableParallelism(),loadAvg1:s,loadAvg5:c,noise:Ie()}}function g(s){if(s.loadAvg1<=s.cores*Je)return;return{code:"noisy-machine",message:`Load average ${s.loadAvg1.toFixed(2)} exceeds 75% of ${s.cores} available core(s); timing noise may be elevated.`,data:{loadAvg1:s.loadAvg1,cores:s.cores}}}var He=500,$e=20,Fe=3,je=10,Ve=2,qe=0.1,ze=1000,Ke=1e4;function Se(s){let c=Math.log10(Math.max(1,s)/1e6),l=Math.round(Fe+Ve*c);return Math.min(je,Math.max(Fe,l))}function Xe(s,c){let l=Math.floor(c/s);return Math.min($e,Math.max(l,Se(s)))}var Ee=0;function x(s){if(typeof s==="number")Ee+=s;else if(s!==void 0&&s!==null)Ee+=1}function fe(s){return s!==null&&typeof s==="object"&&typeof s.then==="function"}function Be(s,c){return Math.max(1,Math.ceil(ze/s),Math.ceil(c/(s*Ke)))}async function F(s,c={}){let l=(c.budgetMs??He)*1e6,w=l*(c.warmup??qe),v=Bun.nanoseconds(),R=0,I=0;while(I<w){let L=s();x(fe(L)?await L:L),R++,I=Bun.nanoseconds()-v}let J;if(R>0)J=Math.max(1,I/R);else{let L=Bun.nanoseconds(),K=s();x(fe(K)?await K:K),J=Math.max(1,Bun.nanoseconds()-L)}let _=Be(J,l);if(_>1){let L=Bun.nanoseconds();for(let K=0;K<_;K++){let b=s();x(fe(b)?await b:b)}J=Math.max(1,(Bun.nanoseconds()-L)/_),_=Be(J,l)}let q=J*_,ne=c.samples??c.minSamples??Xe(q,l),Y=c.samples!==void 0?0:l,H=[],ue=Bun.nanoseconds(),oe=0,ee=0;while(ee<ne||oe<Y){let L=Bun.nanoseconds();for(let b=0;b<_;b++){let T=s();x(fe(T)?await T:T)}let K=Bun.nanoseconds();if(H.push({i:ee,wallNs:(K-L)/_}),ee++,oe=Bun.nanoseconds()-ue,c.gc)Bun.gc(!0);if(c.samples!==void 0&&ee>=c.samples)break}let se=H.map((L)=>L.wallNs),re=u(se),ie=y(re,[],"inprocess"),ae=Se(q);if(H.length<ae)ie.push({code:"low-sample-count",message:`Only ${H.length} sample(s) at ~${Ze(q)} per trial; ${ae} is the floor for this cost class. Raise minSamples or the time budget for a steadier number.`,data:{samples:H.length,target:ae,trialCostNs:q}});return{trials:H,timing:re,warnings:ie}}function Ze(s){if(s>=1e9)return`${(s/1e9).toFixed(2)}s`;if(s>=1e6)return`${(s/1e6).toFixed(1)}ms`;if(s>=1000)return`${(s/1000).toFixed(1)}\xB5s`;return`${s.toFixed(0)}ns`}var he=[],z,de;function ke(s,c,l,w){let v=z;z={name:s,description:l?.description,isolate:l?.isolate,gc:l?.gc,cpu:l?.cpu,alloc:l?.alloc,before:l?.before,after:l?.after,skip:w.skip,only:w.only};try{c()}finally{z=v}}var V=Object.assign((s,c,l)=>ke(s,c,l,{}),{skip:(s,c,l)=>ke(s,c,l,{skip:!0}),only:(s,c,l)=>ke(s,c,l,{only:!0})});function we(s,c,l,w){let v=de!==void 0||l?.params!==void 0?{...de,...l?.params}:void 0;he.push({groupName:z?.name,groupDescription:z?.description,groupIsolate:z?.isolate,groupGc:z?.gc,groupCpu:z?.cpu,groupAlloc:z?.alloc,groupBefore:z?.before,groupAfter:z?.after,name:s,fn:c,baseline:l?.baseline,params:v,skipped:w.skip||z?.skip,only:w.only||z?.only,opts:l})}var G=Object.assign((s,c,l)=>we(s,c,l,{}),{skip:(s,c,l)=>we(s,c,l,{skip:!0}),only:(s,c,l)=>we(s,c,l,{only:!0})});function O(){return he}function B(){he.length=0,z=void 0,de=void 0}function E(s,c){let l=de;de=s;try{return c()}finally{de=l}}function h(s){return s.groupName?`${s.groupName}/${s.name}`:s.name}function C(s,c){return s.opts?.isolate??s.groupIsolate??c}function U(s,c){return s.opts?.gc??s.groupGc??c}function W(s,c){return s.opts?.cpu??s.groupCpu??c}function A(s,c){return s.opts?.alloc??s.groupAlloc??c}function j(s,c){if(!c)return[...s];let l=new RegExp(c);return s.filter((w)=>l.test(h(w)))}
4
- export{k,e,m,n,p,D,N,i,a,S,o,M,r,t,u,y,d,f,g,x,F,V,G,O,B,E,h,C,U,W,A,j};
package/chunk-r5b8vf8w.js DELETED
@@ -1,21 +0,0 @@
1
- // @bun
2
- import{k,e,n,p,D,i,a,S,o,M,t,u,y,d,f,g,E}from"./chunk-qbt85kmg.js";function yn(r){return r.startsWith("file://")?r.slice(7):r}function we(r,h,m){let x=r.nodes,N=x.length,F=new Map,C=[],O=new Map,W=new Int32Array(N);for(let V=0;V<N;V++){let G=x[V],q=G.callFrame,te=yn(q.url),ne=F.get(q.functionName);if(ne===void 0)ne=new Map,F.set(q.functionName,ne);let oe=ne.get(te);if(oe===void 0)oe=C.length,ne.set(te,oe),C.push({key:e("fr",q.functionName,te),name:q.functionName,url:te||void 0,line:q.lineNumber>=0?q.lineNumber:void 0,col:q.columnNumber>=0?q.columnNumber:void 0});W[V]=oe,O.set(G.id,V)}let U=Array(N);for(let V=0;V<N;V++){let G=x[V];U[V]={id:G.id,frameIx:W[O.get(G.id)],children:G.children??[]}}let B=new Float64Array(N),j=new Float64Array(N),{samples:z,timeDeltas:A}=r;for(let V=0;V<z.length;V++){let G=O.get(z[V]);if(G===void 0)continue;B[G]+=A[V]??0,j[G]+=1}let Y=new Int32Array(N).fill(-1);for(let V=0;V<N;V++){let G=x[V].children;if(!G)continue;for(let q of G){let te=O.get(q);if(te!==void 0)Y[te]=V}}let K=[],Z=[];for(let V=N-1;V>=0;V--)if(Y[V]===-1)Z.push(V);while(Z.length>0){let V=Z.pop();K.push(V);let G=x[V].children;if(!G)continue;for(let q of G){let te=O.get(q);if(te!==void 0&&Y[te]===V)Z.push(te)}}let ee=new Float64Array(N);for(let V=K.length-1;V>=0;V--){let G=K[V];ee[G]+=B[G];let q=Y[G];if(q>=0)ee[q]+=ee[G]}let re=Array(C.length),X=[];for(let V=0;V<N;V++){let G=U[V].frameIx,q=re[G];if(q)q.selfUs+=B[V],q.totalUs+=ee[V],q.samples+=j[V];else{let te={frameIx:G,selfUs:B[V],totalUs:ee[V],samples:j[V]};re[G]=te,X.push(te)}}return{origin:h,samplingIntervalUs:m,frames:C,nodes:U,totals:X.sort((V,G)=>G.selfUs-V.selfUs),samples:{nodeIds:r.samples,timeDeltasUs:r.timeDeltas}}}function wn(r,h,m,x){let N=["--cpu-prof","--cpu-prof-dir",h,"--cpu-prof-name",m,"--cpu-prof-interval",String(x)],F=r[0];if(F==="bun"||F?.endsWith("/bun"))return[F,...N,...r.slice(1)];return r}async function Se(r){let h=`${r.artifactDir}/${r.fileName}`,m=r.argv[0],x=m==="bun"||m?.endsWith("/bun"),N=wn(r.argv,r.artifactDir,r.fileName,r.intervalUs),F=x?r.env:{...process.env,...r.env,BUN_OPTIONS:`--cpu-prof --cpu-prof-dir ${r.artifactDir} --cpu-prof-name ${r.fileName} --cpu-prof-interval ${r.intervalUs}`},C=Bun.nanoseconds(),W=await Bun.spawn(N,{cwd:r.cwd,env:F,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,U=Bun.nanoseconds()-C,B=Bun.file(h);if(!await B.exists())return{diagnosticWallNs:U,exitCode:W,warnings:[{code:"artifact-missing",message:`Expected a .cpuprofile at ${h} after exit ${W}, found nothing. The workload's argv[0] must be a \`bun\` binary for CPU capture.`,data:{artifactPath:h,argv:r.argv}}]};let j=await B.json(),z=we(j,"cpu-prof",r.intervalUs),A=j.samples.length===0?[{code:"empty-profile",message:"CPU capture produced zero samples."}]:[];return{diagnosticWallNs:U,exitCode:W,artifactPath:h,cpu:z,warnings:A}}function Ne(r,h="heap-prof"){let{node_fields:m,node_types:x}=r.snapshot.meta,N=m.indexOf("type"),F=m.indexOf("self_size"),C=m.length,O=x[0];if(N===-1||F===-1||!Array.isArray(O))return{origin:h,typeCounts:[],objectCount:r.snapshot.node_count};let W=O.length,U=Array(W),B=new Map,j=[],z=0,A=r.nodes,Y=A.length;for(let X=0;X<Y;X+=C){let V=A[X+N],G=A[X+F]??0;z+=G;let q;if(V>=0&&V<W){if(q=U[V],q===void 0)q={type:O[V],count:0,bytes:0},U[V]=q,j.push(q)}else{let te=`unknown(${V})`;if(q=B.get(te),q===void 0)q={type:te,count:0,bytes:0},B.set(te,q),j.push(q)}q.count++,q.bytes+=G}let K=j.sort((X,V)=>V.count-X.count),Z=K.slice(0,20),ee=K.slice(20),re=Z.map(({type:X,count:V,bytes:G})=>({type:X,count:V,retainedBytes:G}));if(ee.length>0){let X=0,V=0;for(let G of ee)X+=G.count,V+=G.bytes;re.push({type:"other",count:X,retainedBytes:V})}return{origin:h,heapSizeBytes:z,objectCount:r.snapshot.node_count,typeCounts:re}}function xn(r,h,m){let x=["--heap-prof","--heap-prof-dir",h,"--heap-prof-name",m],N=r[0];if(N==="bun"||N?.endsWith("/bun"))return[N,...x,...r.slice(1)];return r}async function Fe(r){let h=`${r.artifactDir}/${r.fileName}`,m=r.argv[0],x=m==="bun"||m?.endsWith("/bun"),N=xn(r.argv,r.artifactDir,r.fileName),F=x?r.env:{...process.env,...r.env,BUN_OPTIONS:`--heap-prof --heap-prof-dir ${r.artifactDir} --heap-prof-name ${r.fileName}`},C=Bun.nanoseconds(),W=await Bun.spawn(N,{cwd:r.cwd,env:F,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,U=Bun.nanoseconds()-C,B=Bun.file(h);if(!await B.exists())return{diagnosticWallNs:U,exitCode:W,warnings:[{code:"artifact-missing",message:`Expected a heap snapshot at ${h} after exit ${W}, found nothing. The workload's argv[0] must be a \`bun\` binary for heap capture.`,data:{artifactPath:h,argv:r.argv}}]};let j=await B.json(),z=Ne(j,"heap-prof");return{diagnosticWallNs:U,exitCode:W,artifactPath:h,heap:z,warnings:[]}}import{Session as kn}from"inspector/promises";var Pn=1000;async function Ue(r,h={}){let m=h.intervalUs??Pn,x=new kn;x.connect();let N=Bun.nanoseconds();try{await x.post("Profiler.enable"),await x.post("Profiler.setSamplingInterval",{interval:m}),await x.post("Profiler.start");let F=await r(),{profile:C}=await x.post("Profiler.stop"),O=Bun.nanoseconds()-N,W=we(C,"inspector",m);return{result:F,cpu:W,diagnosticWallNs:O}}finally{x.disconnect()}}async function ve(r){let h=Bun.nanoseconds(),m=Bun.spawn(r.argv,{cwd:r.cwd,env:r.env,stdout:"ignore",stderr:"ignore",stdin:"ignore"}),x=await m.exited,N=Bun.nanoseconds(),F=m.resourceUsage?.();return{wallNs:N-h,exitCode:x,userNs:F?Number(F.cpuTime.user)*1000:void 0,systemNs:F?Number(F.cpuTime.system)*1000:void 0,maxRssBytes:F?.maxRSS}}function We(r){return r.trim().split(/\s+/).filter(Boolean)}var $n=10,Rn=3000000000,Mn=3;function Te(r){let h=r.warmup??Mn,m=r.samples,x=r.minSamples??$n,N=m??x,F=m!==void 0?0:r.budgetMs!==void 0?r.budgetMs*1e6:Rn,C=[],O=0,W=0;function U(){if(m!==void 0)return W>=m;return W>=N&&O>=F}return{async warmup(){for(let B=0;B<h;B++)await ve(r)},async step(){if(U())return!1;let B=await ve(r);return C.push({i:W,wallNs:B.wallNs,exitCode:B.exitCode,userNs:B.userNs,systemNs:B.systemNs,maxRssBytes:B.maxRssBytes}),O+=B.wallNs,W++,!0},done:U,result(){let B=C.map((A)=>A.wallNs),j=u(B),z=y(j,C.map((A)=>A.exitCode));return{trials:C,timing:j,warnings:z}}}}async function w(r){let h=Te(r);await h.warmup();while(await h.step());return h.result()}var Oe=new URL("./runner.ts",import.meta.url).pathname,vn="node_modules/.cache/ostia";function P(){return Math.max(1,navigator.hardwareConcurrency||1)}async function T(r,h){let m=new Set;for(let x of r){let N=new Bun.Glob(x);for await(let F of N.scan({cwd:h,absolute:!1}))m.add(F)}return[...m].sort()}function Tn(r){if(r===void 0)return;return r==="auto"?P():r}async function I(r,h,m=process.cwd()){return{suites:r.suites.length>0?r.suites:h?.suites?await T(h.suites,m):[],budgetMs:r.budgetMs??h?.budgetMs,samples:r.samples??h?.samples,minSamples:r.minSamples??h?.minSamples,jobs:r.jobs??Tn(h?.jobs),gc:r.gc||(h?.gc??!1),cpu:r.cpu||(h?.cpu??!1),alloc:r.alloc||(h?.alloc??!1),filter:r.filter??h?.filter,isolate:r.isolate||(h?.isolate??!1),preload:r.preload.length>0?r.preload:h?.preload??[],bunFlags:r.bunFlags,outDir:r.outDir??h?.outDir,noiseCheck:r.noiseCheck,cwd:m}}async function c(r){let m=`${r.outDir??vn}/bench-tmp`,x=r.cwd??process.cwd(),N=Math.max(1,Math.floor(r.jobs??1)),F={budgetMs:r.budgetMs,samples:r.samples,minSamples:r.minSamples,gc:r.gc,cpu:r.cpu,alloc:r.alloc,noiseCheck:r.noiseCheck},C=r.suites.map((B)=>B.startsWith("/")?B:`${x}/${B}`),O=(r.preload??[]).map((B)=>B.startsWith("/")?B:`${x}/${B}`),W=r.bunFlags??[],U=async(B,j)=>{let z=new Set,A=0,Y,K=async()=>{while(Y===void 0&&A<B.length){let Z=A++;try{let ee=Bun.spawn(B[Z],{cwd:x,stdout:"inherit",stderr:"inherit",stdin:"ignore"});z.add(ee);let re=await ee.exited;if(z.delete(ee),re!==0)throw Error(`Bench suite failed: ${j(Z)} (runner exited ${re})`)}catch(ee){Y??=ee instanceof Error?ee:Error(String(ee));for(let re of z)re.kill()}}};if(await Promise.all(Array.from({length:Math.min(N,B.length)},K)),Y)throw Y};try{let B=C.map((G)=>`${m}/${e("bench-plan",G)}.json`),j=C.map((G)=>`${m}/${e("bench-primary",G)}.json`),z=C.map((G,q)=>["bun",...W,Oe,G,j[q],JSON.stringify({...F,filter:r.filter,isolate:r.isolate,preload:O,planPath:B[q]})]);await U(z,(G)=>r.suites[G]);let A=await Promise.all(B.map(async(G)=>{let{tasks:q}=await Bun.file(G).json();return q})),Y=await Promise.all(j.map(t)),K=[];for(let G=0;G<A.length;G++)for(let q of A[G])if(q.isolate)K.push({suiteIndex:G,taskIds:[q.id]});let Z=K.map((G,q)=>`${m}/${e("bench-item",C[G.suiteIndex],q)}.json`),ee=K.map((G,q)=>["bun",...W,Oe,C[G.suiteIndex],Z[q],JSON.stringify({...F,taskIds:G.taskIds,preload:O,markIsolated:!0})]);await U(ee,(G)=>r.suites[K[G].suiteIndex]);let re=await Promise.all(Z.map(t)),X=[],V=[];for(let G=0;G<A.length;G++){let q=Y[G],te=new Map;for(let Q of q.measurements){let se=te.get(Q.workloadId)??[];se.push(Q),te.set(Q.workloadId,se)}let ne=0,oe=new Map;K.forEach((Q,se)=>{if(Q.suiteIndex===G)oe.set(Q.taskIds[0],re[se])});for(let Q of A[G])if(Q.isolate){let se=oe.get(Q.id),me=se.workloads[0];X.push(me);for(let le of se.measurements)if(le.workloadId===me.id)V.push(le)}else{let se=q.workloads[ne];X.push(se),ne++;for(let me of te.get(se.id)??[])V.push(me)}}return n(X,V,Y[0]?.environment)}finally{await Bun.spawn(["rm","-rf",m]).exited}}function _(r,h,m=8){if(m<=1)throw RangeError(`range: multiplier must be > 1, got ${m}`);if(r<=0)throw RangeError(`range: start must be > 0, got ${r}`);let x=[];for(let N=r;N<=h;N*=m)x.push(N);if(!x.includes(h))x.push(h);return x}function L(r,h){let m=Object.keys(r),x=(N,F)=>{if(N===m.length){E(F,()=>h(F));return}let C=m[N];for(let O of r[C])x(N+1,{...F,[C]:O})};x(0,{})}function Cn(r){let h=r>>>0;return()=>{h=h+1831565813|0;let m=Math.imul(h^h>>>15,1|h);return m=m+Math.imul(m^m>>>7,61|m)^m,((m^m>>>14)>>>0)/4294967296}}var xe=2000,In=2000;function je(r){let h=r.length,m=h>>1;return h%2===0?(r[m-1]+r[m])/2:r[m]}function Be(r,h){let m=r.length;if(m===1)return r[0];let x=h*(m-1),N=Math.floor(x),F=Math.ceil(x);if(N===F)return r[N];let C=x-N;return r[N]*(1-C)+r[F]*C}function Ee(r,h,m){if(r.length<=m)return r;let x=[...r];for(let N=0;N<m;N++){let F=N+Math.floor(h()*(x.length-N)),C=x[N];x[N]=x[F],x[F]=C}return x.slice(0,m)}function Ae(r,h){let m=r.length,x=new Float64Array(m);for(let N=0;N<m;N++)x[N]=r[Math.floor(h()*m)];return x.sort(),je(x)}function _e(r,h,m={}){let x=m.seed??(Date.now()^Math.imul(r.length,2654435761))>>>0,N=Cn(x),F=m.iterations??In,C=r.length>xe||h.length>xe,O=Ee(r,N,xe),W=Ee(h,N,xe),U=new Float64Array(O);U.sort();let B=je(U),j=new Float64Array(F);for(let z=0;z<F;z++){let A=Ae(O,N),Y=Ae(W,N);j[z]=B===0?Y-A===0?0:1/0:(Y-A)/B*100}return j.sort(),{ci95:[Be(j,0.025),Be(j,0.975)],seed:x,data:{subsampled:C,iterations:F}}}function Dn(r){let h=r<0?-1:1,m=Math.abs(r),x=0.254829592,N=-0.284496736,F=1.421413741,C=-1.453152027,O=1.061405429,W=0.3275911,U=1/(1+0.3275911*m),B=1-((((1.061405429*U+-1.453152027)*U+1.421413741)*U+-0.284496736)*U+0.254829592)*U*Math.exp(-m*m);return h*B}function Sn(r){return 0.5*(1+Dn(r/Math.SQRT2))}function Le(r,h){let m=r.length,x=h.length,N=m+x,F=[...r.map((K)=>({v:K,group:0})),...h.map((K)=>({v:K,group:1}))].sort((K,Z)=>K.v-Z.v),C=new Float64Array(N),O=0,W=0;while(W<N){let K=W;while(K+1<N&&F[K+1].v===F[W].v)K++;let Z=(W+K)/2+1;for(let re=W;re<=K;re++)C[re]=Z;let ee=K-W+1;if(ee>1)O+=ee**3-ee;W=K+1}let U=0;for(let K=0;K<N;K++)if(F[K].group===0)U+=C[K];let B=U-m*(m+1)/2,j=m*x/2,z=Math.sqrt(m*x*(N+1-O/(N*(N-1)))/12),A=z===0?0:(B-j)/z,Y=Math.min(1,Math.max(0,2*(1-Sn(Math.abs(A)))));return{u:B,z:A,pValue:Y}}var l={timingPct:5,frameSelfPct:10,heapTypePct:10,minFrameSelfUs:1000,alpha:0.01,bootstrapIterations:2000},Ce=5;function ke(r,h){if(r===0)return h===0?0:1/0;return(h-r)/r*100}function de(r,h,m){return r.measurements.find((x)=>x.workloadId===h&&x.phase===m)}function b(r,h,m=l){let x=new Set(h.workloads.map((F)=>F.id)),N=[];for(let F of r.workloads){if(!x.has(F.id))continue;let C=v(r,h,F.id,m);if(C)N.push(C)}return N}function v(r,h,m,x=l){let N=de(r,m,"timing"),F=de(h,m,"timing"),C=de(r,m,"cpu"),O=de(h,m,"cpu"),W=de(r,m,"heap"),U=de(h,m,"heap"),B=h.workloads.find((X)=>X.id===m),j=N?.id??C?.id??W?.id,z=F?.id??O?.id??U?.id??B?.id;if(!j||!z)return;let A=!1,Y=[],K=Math.max(x.timingPct,r.environment?.noise.floorPct??0,h.environment?.noise.floorPct??0),Z;if(N?.timing&&B?.skipped&&!F?.timing)Z={medianDeltaPct:0,meanDeltaPct:0,effectPct:0,verdict:"unchanged"},Y.push({code:"skipped",message:"Candidate has no timing measurement for this workload (task.skip()); treated as unchanged.",data:{workloadId:m}});else if(N?.timing&&F?.timing){let X=N.timing.samples,V=F.timing.samples,G=ke(N.timing.median,F.timing.median),q=ke(N.timing.mean,F.timing.mean);if(X.length<Ce||V.length<Ce){let te=G>K?"regressed":G<-K?"improved":"unchanged";if(te==="regressed")A=!0;Z={medianDeltaPct:G,meanDeltaPct:q,effectPct:G,verdict:te},Y.push({code:"thin-comparison",message:`Only ${X.length} baseline / ${V.length} candidate sample(s); falling back to a point-estimate threshold instead of a bootstrap CI and Mann-Whitney test (needs ${Ce}+ per side).`,data:{baseSamples:X.length,candSamples:V.length}})}else{let te=_e(X,V,{iterations:x.bootstrapIterations}),ne=Le(X,V),oe=te.ci95[0]>K&&ne.pValue<x.alpha?"regressed":te.ci95[1]<-K&&ne.pValue<x.alpha?"improved":"unchanged";if(oe==="regressed")A=!0;Z={medianDeltaPct:G,meanDeltaPct:q,effectPct:G,ci95:te.ci95,pValue:ne.pValue,seed:te.seed,verdict:oe}}}let ee;if(C?.cpu&&O?.cpu){let X=new Map(C.cpu.totals.map((ne)=>[C.cpu.frames[ne.frameIx].key,ne])),V=new Map(O.cpu.totals.map((ne)=>[O.cpu.frames[ne.frameIx].key,ne])),G=new Map(C.cpu.frames.map((ne)=>[ne.key,ne.name])),q=new Map(O.cpu.frames.map((ne)=>[ne.key,ne.name]));ee=[...new Set([...X.keys(),...V.keys()])].map((ne)=>{let oe=X.get(ne)?.selfUs??0,Q=V.get(ne)?.selfUs??0;return{frameKey:ne,name:q.get(ne)??G.get(ne)??ne,baseSelfUs:oe,candSelfUs:Q,deltaPct:ke(oe,Q)}}).sort((ne,oe)=>Math.abs(oe.deltaPct)-Math.abs(ne.deltaPct));for(let ne of ee)if((ne.baseSelfUs>=x.minFrameSelfUs||ne.candSelfUs>=x.minFrameSelfUs)&&ne.deltaPct>x.frameSelfPct)A=!0}let re;if(W?.heap&&U?.heap){let X=new Map(W.heap.typeCounts.map((q)=>[q.type,q])),V=new Map(U.heap.typeCounts.map((q)=>[q.type,q]));re=[...new Set([...X.keys(),...V.keys()])].map((q)=>{let te=X.get(q),ne=V.get(q);return{type:q,baseCount:te?.count??0,candCount:ne?.count??0,baseBytes:te?.retainedBytes,candBytes:ne?.retainedBytes,deltaPct:ke(te?.count??0,ne?.count??0)}}).sort((q,te)=>Math.abs(te.deltaPct)-Math.abs(q.deltaPct));for(let q of re)if(q.deltaPct>x.heapTypePct)A=!0}return{id:e("cmp",j,z),baselineMeasurementId:j,candidateMeasurementId:z,timing:Z,...Y.length>0&&{warnings:Y},frames:ee,heapTypes:re,thresholds:{...x,effectiveTimingPct:K},verdict:A?"fail":"pass"}}function pe(r,h){if(h){let m=r.measurements.find((x)=>x.id===h);return m?.cpu?[m]:[]}return r.measurements.filter((m)=>m.phase==="cpu"&&m.cpu)}function fe(r){let h=r.nodes,m=h.length,x=Nn(r),N=new Int32Array(m).fill(-1);for(let W=0;W<m;W++)for(let U of h[W].children){let B=x(U);if(B!==-1)N[B]=W}let F=[];for(let W=0;W<m;W++)if(N[W]===-1)F.push(W);let C=[],O=[];for(let W=F.length-1;W>=0;W--)O.push(F[W]);while(O.length>0){let W=O.pop();C.push(W);for(let U of h[W].children){let B=x(U);if(B!==-1&&N[B]===W)O.push(B)}}return{count:m,indexOf:x,parentIx:N,roots:F,order:C}}function Nn(r){let h=r.nodes,m=h.length,x=1/0,N=-1/0,F=!0;for(let O=0;O<m;O++){let W=h[O].id;if(!Number.isInteger(W)){F=!1;break}if(W<x)x=W;if(W>N)N=W}if(F&&m>0&&N-x<m*4+64){let O=N-x+1,W=new Int32Array(O).fill(-1);for(let U=0;U<m;U++)W[h[U].id-x]=U;return(U)=>{let B=U-x;return B>=0&&B<O?W[B]:-1}}let C=new Map;for(let O=0;O<m;O++)C.set(h[O].id,O);return(O)=>C.get(O)??-1}function Ve(r,h){let{count:m,indexOf:x,parentIx:N,order:F}=h,C=new Float64Array(m),O=new Float64Array(m),W=r.samples?.nodeIds??[],U=r.samples?.timeDeltasUs??[];for(let j=0;j<W.length;j++){let z=x(W[j]);if(z===-1)continue;C[z]+=U[j]??0,O[z]+=1}let B=new Float64Array(m);for(let j=F.length-1;j>=0;j--){let z=F[j];B[z]+=C[z];let A=N[z];if(A>=0)B[A]+=B[z]}return{selfUs:C,totalUs:B,samples:O}}var He={name:"collapsed",async render(r,h={}){return{files:pe(r,h.measurementId).map((N)=>{let F=N.cpu,{nodes:C,frames:O}=F,W=fe(F),U=Array(W.count);for(let Y of W.order){let K=O[C[Y].frameIx].name||"(anonymous)",Z=W.parentIx[Y];U[Y]=Z===-1?K:`${U[Z]};${K}`}let B=new Float64Array(W.count),j=[],z=F.samples?.nodeIds??[];for(let Y=0;Y<z.length;Y++){let K=W.indexOf(z[Y]);if(K===-1)continue;if(B[K]++===0)j.push(K)}let A=Array(j.length);for(let Y=0;Y<j.length;Y++){let K=j[Y];A[Y]=`${U[K]} ${B[K]}`}return{path:`${N.id}.collapsed.txt`,content:A.join(`
3
- `)+(A.length>0?`
4
- `:"")}})}}};var ze={name:"cpuprofile",async render(r,h={}){let m=pe(r,h.measurementId),x=[],N=[];for(let F of m){if(F.cpu?.origin!=="cpu-prof"&&F.cpu?.origin!=="inspector"){N.push(`${F.id} (origin ${F.cpu?.origin??"unknown"} has no .cpuprofile artifact to pass through)`);continue}let C=F.artifacts.find((W)=>W.kind==="cpuprofile");if(!C){N.push(`${F.id} (no cpuprofile artifact recorded on this run)`);continue}let O=Bun.file(C.path);if(!await O.exists()){N.push(`${F.id} (artifact missing on disk: ${C.path})`);continue}x.push({path:`${F.id}.cpuprofile`,content:await O.text()})}if(x.length===0&&N.length>0)return{text:`No .cpuprofile artifacts available:
5
- ${N.map((F)=>` - ${F}`).join(`
6
- `)}
7
- `};return{files:x}}};var Ke={name:"json",async render(r){return{text:M(r)}}};var Ge={name:"jsonl",async render(r){let{measurements:h,...m}=r;return{text:`${[k(m),...h.map((N)=>k(N))].join(`
8
- `)}
9
- `}}};var Fn={ns:1,\u{b5}s:1000,ms:1e6,s:1e9};function be(r){let h=Math.abs(r);if(h>=1e9)return"s";if(h>=1e6)return"ms";if(h>=1000)return"\xB5s";return"ns"}function Un(r){let h=Math.floor(Math.log10(Math.max(Math.abs(r),1)))+1;return Math.max(1,3-h)}function ae(r,h=be(r)){let m=r/Fn[h];return`${m.toFixed(Un(m))} ${h}`}function Pe(r){return`${r.cpuModel} \xB7 ${r.cores} cores \xB7 load ${r.loadAvg1.toFixed(1)} \xB7 noise floor ${r.noise.floorPct.toFixed(1)}%`}function Je(r){return(r/1e6).toFixed(3)}function ye(r){return r?.label??r?.command?.join(" ")??r?.entry?.task??r?.id??"unknown"}function Ye(r){if(!r?.params)return"";return` (${Object.entries(r.params).map(([m,x])=>`${m}=${x}`).join(", ")})`}function Wn(r){let h;for(let m of r){let x=m?.params?Object.keys(m.params):void 0;if(x?.length!==2)return;if(h===void 0)h=x;else if(x.length!==h.length||x.some((N,F)=>N!==h[F]))return}return h}var qe=10,Qe=10,Xe={name:"markdown",async render(r){let h=new Map(r.workloads.map((C)=>[C.id,C])),m=[];m.push("# Profile Report","");let x=r.git?` \xB7 ${r.git.sha} (${r.git.branch}${r.git.dirty?", dirty":""})`:"";if(m.push(`Bun ${r.bunVersion} \xB7 ostia ${r.toolVersion} \xB7 ${r.platform.os}/${r.platform.arch} \xB7 ${r.createdAt}${x}`,""),r.environment)m.push(Pe(r.environment),"");let N=r.measurements.filter((C)=>C.phase==="timing"&&C.timing!==void 0),F=r.workloads.filter((C)=>C.skipped&&!N.some((O)=>O.workloadId===C.id));if(N.length>0||F.length>0){m.push("## Timing","");let C=new Map,O=[];for(let B of N){let j=h.get(B.workloadId)?.entry?.group;if(j===void 0){O.push(B);continue}let z=C.get(j);if(z)z.push(B);else C.set(j,[B])}let W=new Map;for(let[B,j]of C){let z=Wn(j.map((A)=>h.get(A.workloadId)));if(z)W.set(B,{keys:z,runs:j});else O.push(...j)}if(O.length>0||F.length>0){m.push("| Task | Median | Spread (p75\u2026p99) | Mean \xB1 SD | Range | MAD |","|---|---|---|---|---|---|");for(let B of O){let j=h.get(B.workloadId),z=ye(j)+Ye(j),A=B.timing,Y=be(A.median),K=A.p75??A.median,Z=A.p99??A.max,ee=A.mad!==void 0?ae(A.mad,Y):"-";m.push(`| ${z} | ${ae(A.median,Y)} | ${ae(K,Y)}\u2026${ae(Z,Y)} | ${ae(A.mean,Y)} \xB1 ${ae(A.stddev,Y)} | ${ae(A.min,Y)}\u2026${ae(A.max,Y)} | ${ee} |`)}for(let B of F){let j=ye(B)+Ye(B);m.push(`| ${j} | - skipped | - | - | - | - |`)}m.push("")}for(let[B,{keys:j,runs:z}]of W){let[A,Y]=j,K=[],Z=[],ee=new Map;for(let re of z){let X=h.get(re.workloadId).params,V=X[A],G=X[Y];if(!K.includes(V))K.push(V);if(!Z.includes(G))Z.push(G);ee.set(`${V}\x00${G}`,re)}m.push(`### ${B} (${A} \xD7 ${Y})`,""),m.push(`| ${A} \\ ${Y} | ${Z.join(" | ")} |`,`|---|${Z.map(()=>"---").join("|")}|`);for(let re of K){let X=Z.map((V)=>{let G=ee.get(`${re}\x00${V}`);return G?ae(G.timing.median):"-"});m.push(`| ${re} | ${X.join(" | ")} |`)}m.push("")}let U=N.filter((B)=>B.warnings.length>0);if(U.length>0){m.push("### Warnings","");for(let B of U){let j=ye(h.get(B.workloadId));for(let z of B.warnings)m.push(`- **${j}**: ${z.message} (\`${z.code}\`)`)}m.push("")}}for(let C of r.measurements){if(C.phase!=="cpu"&&C.phase!=="heap")continue;let O=ye(h.get(C.workloadId));if(C.phase==="cpu"){if(m.push(`## CPU capture - ${O}`,""),m.push(`instrumented, diagnostic wall ${Je(C.diagnosticWallNs??0)}ms`,""),C.cpu){m.push(`origin: \`${C.cpu.origin}\`, interval: ${C.cpu.samplingIntervalUs}\xB5s`,""),m.push("| Self % | Self (ms) | Total (ms) | Frame |","|---|---|---|---|");let W=C.cpu.totals.reduce((U,B)=>U+B.selfUs,0)||1;for(let U of C.cpu.totals.slice(0,qe)){let B=C.cpu.frames[U.frameIx],j=(U.selfUs/W*100).toFixed(1);m.push(`| ${j}% | ${(U.selfUs/1000).toFixed(2)} | ${(U.totalUs/1000).toFixed(2)} | ${B?.name||"(anonymous)"} |`)}if(m.push(""),C.jit){let U=C.jit.tiers;m.push(`JIT tiers: LLInt ${U.llint} \xB7 Baseline ${U.baseline} \xB7 DFG ${U.dfg} \xB7 FTL ${U.ftl}`,"")}}}else if(m.push(`## Heap snapshot - ${O}`,""),m.push(`instrumented, diagnostic wall ${Je(C.diagnosticWallNs??0)}ms`,""),C.heap){m.push(`${C.heap.objectCount??"?"} objects, ${((C.heap.heapSizeBytes??0)/1e6).toFixed(2)}MB`,""),m.push("| Count | Type |","|---|---|");for(let W of C.heap.typeCounts.slice(0,Qe))m.push(`| ${W.count} | ${W.type} |`);m.push("")}for(let W of C.artifacts)m.push(`- artifact: \`${W.path}\``);for(let W of C.warnings)m.push(`- ! ${W.message} (\`${W.code}\`)`);if(C.artifacts.length>0||C.warnings.length>0)m.push("")}if(r.comparisons&&r.comparisons.length>0){m.push("## Comparisons","");for(let C of r.comparisons){let O=r.measurements.find((U)=>U.id===C.candidateMeasurementId),W=ye(O?h.get(O.workloadId):h.get(C.candidateMeasurementId));if(m.push(`### ${C.verdict==="pass"?"\u2713":"\u2717"} ${W}`,""),C.timing){let U=C.timing.medianDeltaPct>0?"+":"";m.push(`- timing: ${U}${C.timing.medianDeltaPct.toFixed(1)}% median (**${C.timing.verdict}**)`)}for(let U of C.frames?.slice(0,qe)??[]){if(Math.abs(U.deltaPct)<0.5)continue;let B=U.deltaPct>0?"+":"";m.push(`- frame \`${U.name}\`: ${B}${U.deltaPct.toFixed(1)}% self-time (${(U.baseSelfUs/1000).toFixed(2)}ms \u2192 ${(U.candSelfUs/1000).toFixed(2)}ms)`)}for(let U of C.heapTypes?.slice(0,Qe)??[]){if(Math.abs(U.deltaPct)<0.5)continue;let B=U.deltaPct>0?"+":"";m.push(`- heap \`${U.type}\`: ${B}${U.deltaPct.toFixed(1)}% count (${U.baseCount} \u2192 ${U.candCount})`)}m.push("")}}return{text:m.join(`
10
- `)}}};var On=15;function Ie(r){return`n${r}`}function Bn(r,h,m){return`${(r||"(anonymous)").replace(/"/g,"'")} (self ${(h/1000).toFixed(2)}ms, total ${(m/1000).toFixed(2)}ms)`}function En(r,h,m,x){let N=[];if(x<=0)return N;for(let F=0;F<h;F++){if(F===m)continue;let C=r[F];if(N.length===x&&C<=r[N[x-1]])continue;let O=N.length;while(O>0&&r[N[O-1]]<C)O--;if(N.splice(O,0,F),N.length>x)N.pop()}return N}var Ze={name:"mermaid",async render(r,h={}){let m=h.topN??On;return{files:pe(r,h.measurementId).map((F)=>{let C=F.cpu,{nodes:O,frames:W}=C,U=fe(C),{selfUs:B,totalUs:j}=Ve(C,U),{parentIx:z}=U,A=U.roots[0]??-1,Y=En(B,U.count,A,m),K=new Set(A!==-1?[A]:[]),Z=[];for(let re of Y){Z.length=0;for(let X=re;X!==-1;X=z[X])Z.push(X);for(let X=Z.length-1;X>=0;X--)K.add(Z[X])}let ee=["graph TD"];for(let re of K){let X=O[re].id;ee.push(` ${Ie(X)}["${Bn(W[O[re].frameIx].name,B[re],j[re])}"]`)}for(let re of K){let X=z[re];if(X!==-1&&K.has(X))ee.push(` ${Ie(O[X].id)} --> ${Ie(O[re].id)}`)}return{path:`${F.id}.mermaid.md`,content:`${ee.join(`
11
- `)}
12
- `}})}}};function en(r){if(!r?.entry)return;if(r.entry.group!==void 0)return r.entry.group;let h=r.entry.task,m=h.lastIndexOf("/");return m===-1?void 0:h.slice(0,m)}function $e(r){let h=Math.min(...r.map((N)=>N.run.timing.median)),m=new Map;for(let N of r){let F=en(N.workload);if(F===void 0)continue;let C=m.get(F);if(C)C.push(N);else m.set(F,[N])}let x=new Map;for(let N of r){let F=en(N.workload);if(F===void 0){x.set(N,h);continue}let C=m.get(F)??[N],O=C.find((W)=>W.workload?.baseline);x.set(N,O?O.run.timing.median:Math.min(...C.map((W)=>W.run.timing.median)))}return x}function ie(r){return Number.isFinite(r)?Number(r.toPrecision(6)):r}function An(r,h){return r?.entry?.task??r?.label??r?.command?.join(" ")??h.workloadId}function jn(r,h){let m={task:r.entry?.task??r.label??r.id,skipped:!0,warnings:[]};if(r.entry?.group!==void 0)m.group=r.entry.group;if(r.description!==void 0)m.description=r.description;if(r.groupDescription!==void 0)m.groupDescription=r.groupDescription;if(r.params!==void 0)m.params=r.params;if(h?.timing)m.delta={medianPct:ie(h.timing.medianDeltaPct),meanPct:ie(h.timing.meanDeltaPct),verdict:h.timing.verdict,pass:h.verdict==="pass"};return m}function _n(r){let h=new Map(r.workloads.map((U)=>[U.id,U])),m=r.measurements.filter((U)=>U.phase==="timing"&&U.timing!==void 0).map((U)=>({run:U,workload:h.get(U.workloadId)})),x=m.length>1?$e(m):void 0,N=new Map((r.comparisons??[]).map((U)=>[U.candidateMeasurementId,U])),F=new Set(m.map((U)=>U.run.workloadId)),C=new Map;for(let U of r.measurements){if(U.phase!=="cpu"||U.warnings.length===0)continue;let B=C.get(U.workloadId)??[];C.set(U.workloadId,[...B,...U.warnings])}let O=r.workloads.filter((U)=>U.skipped&&!F.has(U.id)).map((U)=>jn(U,N.get(U.id)));return[...m.map((U)=>{let{run:B,workload:j}=U,z=B.timing,A={task:An(j,B),unit:"ns",samples:z.samples.length,mean:ie(z.mean),median:ie(z.median),stddev:ie(z.stddev),stddevPct:ie(z.mean===0?0:z.stddev/z.mean*100),min:ie(z.min),max:ie(z.max),warnings:[...B.warnings,...C.get(B.workloadId)??[]].map((K)=>K.data?{code:K.code,data:K.data}:{code:K.code})};if(z.p75!==void 0)A.p75=ie(z.p75);if(z.p99!==void 0)A.p99=ie(z.p99);if(z.mad!==void 0)A.mad=ie(z.mad);if(j?.entry?.group!==void 0)A.group=j.entry.group;if(j?.description!==void 0)A.description=j.description;if(j?.groupDescription!==void 0)A.groupDescription=j.groupDescription;if(j?.params!==void 0)A.params=j.params;if(x)A.relative=ie(z.median/(x.get(U)??z.median));if(j?.baseline)A.baseline=!0;let Y=N.get(B.id);if(Y?.timing){if(A.delta={medianPct:ie(Y.timing.medianDeltaPct),meanPct:ie(Y.timing.meanDeltaPct),verdict:Y.timing.verdict,pass:Y.verdict==="pass"},Y.timing.ci95)A.delta.ci95=[ie(Y.timing.ci95[0]),ie(Y.timing.ci95[1])];if(Y.timing.pValue!==void 0)A.delta.pValue=ie(Y.timing.pValue)}return A}),...O]}var nn={name:"minimal",async render(r){let h=_n(r).map((m)=>JSON.stringify(m));return{text:h.length>0?`${h.join(`
13
- `)}
14
- `:""}}};var Ln="https://www.speedscope.app/file-format-schema.json";function tn(r){return r?.label??r?.command?.join(" ")??r?.entry?.task??"profile"}var rn={name:"speedscope",async render(r,h={}){let m=pe(r,h.measurementId),x=new Map(r.workloads.map((F)=>[F.id,F]));return{files:m.map((F)=>{let C=F.cpu,{nodes:O}=C,W=fe(C),U=C.samples?.nodeIds??[],B=C.samples?.timeDeltasUs??[],j=Array(W.count);for(let K of W.order){let Z=W.parentIx[K],ee=O[K].frameIx;j[K]=Z===-1?[ee]:[...j[Z],ee]}let z=Array(U.length);for(let K=0;K<U.length;K++){let Z=W.indexOf(U[K]);z[K]=Z===-1?[]:j[Z]}let A=0;for(let K=0;K<B.length;K++)A+=B[K];let Y={$schema:Ln,exporter:"ostia",name:tn(x.get(F.workloadId)),activeProfileIndex:0,shared:{frames:C.frames.map((K)=>({name:K.name||"(anonymous)",file:K.url,line:K.line!==void 0?K.line+1:void 0}))},profiles:[{type:"sampled",name:tn(x.get(F.workloadId)),unit:"microseconds",startValue:0,endValue:A,samples:z,weights:B}]};return{path:`${F.id}.speedscope.json`,content:`${JSON.stringify(Y,null,2)}
15
- `}})}}};function Vn(r){return(r/1e6).toFixed(3)}function Hn(r){if(r<1024)return`${r.toFixed(0)}B`;if(r<1048576)return`${(r/1024).toFixed(2)}KB`;return`${(r/1048576).toFixed(2)}MB`}function Re(r){return r.label??r.command?.join(" ")??r.entry?.task??r.id}function zn(r){if(!r?.entry)return;if(r.entry.group!==void 0)return r.entry.group;let h=r.entry.task,m=h.lastIndexOf("/");return m===-1?void 0:h.slice(0,m)}var on={name:"table",async render(r){let h=r.measurements.filter((Q)=>Q.phase==="timing"&&Q.timing!==void 0),m=new Map(r.workloads.map((Q)=>[Q.id,Q])),x=r.environment?[Pe(r.environment),""]:[],N=r.workloads.filter((Q)=>Q.skipped&&!h.some((se)=>se.workloadId===Q.id));if(h.length===0&&N.length===0){let Q=sn(r,m);return{text:Q.length>0?`${[...x,...Q].join(`
16
- `)}
17
- `:`(no timing runs)
18
- `}}let F=new Map(h.map((Q)=>[Q.workloadId,Q])),C=[];for(let Q of r.workloads){let se=F.get(Q.id);if(se)C.push({kind:"measured",run:se,workload:Q,label:Re(Q)});else if(Q.skipped)C.push({kind:"skipped",workload:Q,label:Re(Q)})}let O=C.filter((Q)=>Q.kind==="measured"),W=new Map(r.measurements.filter((Q)=>Q.phase==="memstats"&&Q.memory?.bytesPerOp!==void 0).map((Q)=>[Q.workloadId,Q.memory.bytesPerOp])),U=W.size>0,B=O.length>1,j=$e(O),z=new Map,A=new Map,Y;for(let Q of C){let se=zn(Q.workload);if(se!==Y){if(se!==void 0)A.set(Q,se);Y=se}z.set(Q,se!==void 0?" ":"")}let K=Math.max(4,...C.map((Q)=>z.get(Q).length+Q.label.length)),Z=10,ee=18,re=18,X=10,V=[...x],G=U?` ${"Alloc/op".padEnd(X)}`:"",q=`${"Task".padEnd(K)} ${"Median".padEnd(Z)} ${"Spread".padEnd(ee)} ${"Range".padEnd(re)}${G}${B?" Relative":""}`;V.push(q),V.push("-".repeat(q.length));let te=[];for(let Q of C){let se=A.get(Q);if(se!==void 0)V.push(`${se}:`);let me=z.get(Q);if(Q.kind==="skipped"){V.push(`${(me+Q.label).padEnd(K)} - skipped`);continue}let{run:le,label:pn,workload:Me}=Q,ce=le.timing,ge=be(ce.median),ln=ce.p75??ce.median,dn=ce.p99??ce.max,fn=ae(ce.median,ge),gn=`${ae(ln,ge)}\u2026${ae(dn,ge)}`,hn=`${ae(ce.min,ge)}\u2026${ae(ce.max,ge)}`,he=`${(me+pn).padEnd(K)} ${fn.padEnd(Z)} ${gn.padEnd(ee)} ${hn.padEnd(re)}`;if(U){let ue=Me?W.get(Me.id):void 0,bn=ue!==void 0?Hn(ue):"";he+=` ${bn.padEnd(X)}`}if(B){let ue=ce.median/(j.get(Q)??ce.median);if(ue===1)he+=Me?.baseline?" 1.00\xD7 (baseline)":" 1.00\xD7";else if(ue>1)he+=` ${ue.toFixed(2)}\xD7 slower`;else he+=` ${(1/ue).toFixed(2)}\xD7 faster`}if(V.push(he),le.warnings.length>0)V.push(`${" ".repeat(me.length)} ! ${le.warnings.map((ue)=>ue.code).join(", ")}`),te.push(Q)}if(te.length>0){V.push(""),V.push("Warnings:");for(let Q of te)for(let se of Q.run.warnings)V.push(` ${Q.label}: ${se.message}`)}let ne=Gn(r,m);if(ne.length>0)V.push(""),V.push(...ne);let oe=sn(r,m);if(oe.length>0)V.push(""),V.push(...oe);return{text:`${V.map((Q)=>Q.trimEnd()).join(`
19
- `)}
20
- `}}};function Kn(r,h,m){let x=r.measurements.find((F)=>F.id===m),N=x?h.get(x.workloadId):h.get(m);return N?Re(N):m}function sn(r,h){if(!r.comparisons||r.comparisons.length===0)return[];let m=[];for(let x of r.comparisons){let N=Kn(r,h,x.candidateMeasurementId),F=x.verdict==="pass"?"\u2713":"\u2717";if(m.push(`${F} ${N}`),x.timing){let C=(O)=>`${O>=0?"+":""}${O.toFixed(1)}%`;if(x.timing.ci95&&x.timing.pValue!==void 0){let O=x.timing.pValue<0.001?"p<0.001":`p=${x.timing.pValue.toFixed(3)}`;m.push(` timing: ${C(x.timing.medianDeltaPct)} median, 95% CI [${C(x.timing.ci95[0])}, ${C(x.timing.ci95[1])}], ${O} (${x.timing.verdict})`)}else m.push(` timing: ${C(x.timing.medianDeltaPct)} median (${x.timing.verdict})`)}if(x.frames)for(let C of x.frames.slice(0,an)){if(Math.abs(C.deltaPct)<0.5)continue;let O=C.deltaPct>0?"+":"";m.push(` frame ${C.name}: ${O}${C.deltaPct.toFixed(1)}% self-time (${(C.baseSelfUs/1000).toFixed(2)}ms -> ${(C.candSelfUs/1000).toFixed(2)}ms)`)}if(x.heapTypes)for(let C of x.heapTypes.slice(0,cn)){if(Math.abs(C.deltaPct)<0.5)continue;let O=C.deltaPct>0?"+":"";m.push(` heap ${C.type}: ${O}${C.deltaPct.toFixed(1)}% count (${C.baseCount} -> ${C.candCount})`)}}return m}var an=5,cn=5;function Gn(r,h){let m=[];for(let x of r.measurements){if(x.phase!=="cpu"&&x.phase!=="heap")continue;let N=h.get(x.workloadId),F=N?Re(N):x.workloadId;if(x.phase==="cpu")if(x.cpu){m.push(`CPU capture - ${F} (instrumented, ${x.cpu.samplingIntervalUs}\xB5s interval, diagnostic wall ${Vn(x.diagnosticWallNs??0)}ms)`);let C=x.cpu.totals.reduce((O,W)=>O+W.selfUs,0)||1;for(let O of x.cpu.totals.slice(0,an)){let W=x.cpu.frames[O.frameIx],U=(O.selfUs/C*100).toFixed(1);m.push(` ${U.padStart(5)}% ${(O.selfUs/1000).toFixed(2).padStart(8)}ms self ${W?.name??"?"}`)}}else m.push(`CPU capture - ${F} (instrumented, no evidence captured)`);else if(x.heap){let C=((x.heap.heapSizeBytes??0)/1e6).toFixed(2);m.push(`Heap snapshot - ${F} (instrumented, ${x.heap.objectCount??"?"} objects, ${C}MB)`);for(let O of x.heap.typeCounts.slice(0,cn))m.push(` ${String(O.count).padStart(6)} ${O.type}`)}else m.push(`Heap snapshot - ${F} (instrumented, no evidence captured)`);for(let C of x.artifacts)m.push(` artifact: ${C.path}`);for(let C of x.warnings)m.push(` ! ${C.message}`)}return m}var s={table:on,json:Ke,markdown:Xe,jsonl:Ge,minimal:nn,collapsed:He,mermaid:Ze,speedscope:rn,cpuprofile:ze};function H(r){return r}var Jn="node_modules/.cache/ostia",De=1000;async function R(r){let h=o({samples:r.samples??null,budgetMs:r.budgetMs??null,minSamples:r.minSamples??null,warmup:r.warmup??null,cpu:r.cpu??!1,heap:r.heap??!1,cpuIntervalUs:r.cpuIntervalUs??De}),x=`${r.outDir??Jn}/artifacts`,N=r.noiseCheck===!1?void 0:f(),F=N?g(N):void 0,C=[],O=[],W=r.commands.map((j)=>{let z=Array.isArray(j)?j:We(j),A=p(z,Array.isArray(j)?void 0:j);return{argv:z,workload:A}}),U=(r.interleave??!0)&&W.length>1,B=(j)=>({argv:j,cwd:r.cwd,env:r.env,samples:r.samples,budgetMs:r.budgetMs,minSamples:r.minSamples,warmup:r.warmup});if(U){let j=W.map(({argv:A})=>Te(B(A)));for(let A of j)await A.warmup();let z=!0;while(z){z=!1;for(let A of j)if(await A.step())z=!0}for(let A=0;A<W.length;A++){let{argv:Y,workload:K}=W[A];C.push(K);let Z=j[A].result(),ee=i({workload:K,configFingerprint:h,trials:Z.trials,timing:Z.timing,warnings:F&&O.length===0?[...Z.warnings,F]:Z.warnings,interleaved:!0});O.push(ee),O.push(...await un(K,Y,ee.id,h,r,x))}return n(C,O,N)}for(let{argv:j,workload:z}of W){C.push(z);let A=await w(B(j)),Y=i({workload:z,configFingerprint:h,trials:A.trials,timing:A.timing,warnings:F&&O.length===0?[...A.warnings,F]:A.warnings});O.push(Y),O.push(...await un(z,j,Y.id,h,r,x))}return n(C,O,N)}async function un(r,h,m,x,N,F){let C=[];if(N.cpu){let O=`${m}-cpu.cpuprofile`,W=await Se({argv:h,cwd:N.cwd,env:N.env,artifactDir:F,fileName:O,intervalUs:N.cpuIntervalUs??De});C.push(await mn({workload:r,phase:"cpu",configFingerprint:x,diagnosticWallNs:W.diagnosticWallNs,exitCode:W.exitCode,cpu:W.cpu,artifactPath:W.artifactPath,artifactKind:"cpuprofile",warnings:W.warnings}))}if(N.heap){let O=`${m}-heap.heapsnapshot`,W=await Fe({argv:h,cwd:N.cwd,env:N.env,artifactDir:F,fileName:O});C.push(await mn({workload:r,phase:"heap",configFingerprint:x,diagnosticWallNs:W.diagnosticWallNs,exitCode:W.exitCode,heap:W.heap,artifactPath:W.artifactPath,artifactKind:"heapsnapshot",warnings:W.warnings}))}return C}async function mn(r){let h=`${r.workload.id}-${r.phase}-${r.configFingerprint}`,m=r.artifactPath?[await S(h,r.artifactKind,r.artifactPath)]:[];return a({workload:r.workload,phase:r.phase,configFingerprint:r.configFingerprint,diagnosticWallNs:r.diagnosticWallNs,exitCode:r.exitCode,cpu:r.cpu,heap:r.heap,warnings:r.warnings,artifacts:m})}async function J(r,h={}){let m=D(r),x=o({intervalUs:h.intervalUs??De,origin:h.origin??"inspector"}),N=(U)=>U.samples?.nodeIds.length===0?[{code:"empty-profile",message:"In-process capture produced zero samples."}]:[];if(h.origin==="jsc"){let{result:U,cpu:B,jit:j,diagnosticWallNs:z}=await d(r,h),A=a({workload:m,phase:"cpu",configFingerprint:x,diagnosticWallNs:z,cpu:B,jit:j,warnings:N(B),artifacts:[]});return{result:U,measurement:A,document:n([m],[A])}}let{result:F,cpu:C,diagnosticWallNs:O}=await Ue(r,h),W=a({workload:m,phase:"cpu",configFingerprint:x,diagnosticWallNs:O,cpu:C,warnings:N(C),artifacts:[]});return{result:F,measurement:W,document:n([m],[W])}}
21
- export{P,T,I,c,l,b,v,w,_,L,s,H,R,J};