ostia 0.1.0 → 0.1.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.
@@ -0,0 +1,4 @@
1
+ // @bun
2
+ function N(n){return JSON.stringify(d(n))}function d(n){if(Array.isArray(n))return n.map(d);if(n!==null&&typeof n==="object"){let e={};for(let r of Object.keys(n).sort())e[r]=d(n[r]);return e}return n}function c(n,...e){let r=Bun.CryptoHasher.hash("sha256",N(e),"hex");return`${n}_${r.slice(0,16)}`}var k="0.1.0";function E(n,e){return{schemaVersion:1,toolVersion:k,bunVersion:Bun.version,platform:{os:process.platform,arch:process.arch},createdAt:new Date().toISOString(),workloads:n,runs:e}}function O(n,e){return{id:c("wl","subprocess",n,process.cwd()),kind:"subprocess",command:n,label:e}}function C(n,e){return{id:c("wl","inprocess",n.name,n.toString()),kind:"inprocess",label:e}}function q(n,e,r){return{id:c("wl","inprocess-entry",n,e),kind:"inprocess",entry:{file:n,task:e},label:r}}function _(n){return{id:c("run",n.workload.id,"timing",n.configFingerprint,Bun.version,k),workloadId:n.workload.id,phase:"timing",instrumented:!1,configFingerprint:n.configFingerprint,trials:n.trials,timing:n.timing,warnings:n.warnings,artifacts:[],memory:B(n.trials)}}function B(n){let e=n.map((r)=>r.maxRssBytes).filter((r)=>r!==void 0);if(e.length===0)return;return{origin:"resourceUsage",perTrial:n.map((r)=>({rssBytes:r.maxRssBytes})),maxRssBytes:Math.max(...e)}}function H(n){return{id:c("run",n.workload.id,n.phase,n.configFingerprint,Bun.version,k),workloadId:n.workload.id,phase:n.phase,instrumented:!0,configFingerprint:n.configFingerprint,trials:[{i:0,wallNs:n.diagnosticWallNs,exitCode:n.exitCode}],diagnosticWallNs:n.diagnosticWallNs,cpu:n.cpu,heap:n.heap,jit:n.jit,warnings:n.warnings,artifacts:n.artifacts}}async function J(n,e,r){let i=await Bun.file(r).arrayBuffer(),o=new Bun.CryptoHasher("sha256");return o.update(i),{id:c("art",n,e,r),kind:e,path:r,sha256:o.digest("hex"),bytes:i.byteLength}}function j(n){return c("cfg",n)}function D(n){return`${JSON.stringify(d(n),null,2)}
3
+ `}async function L(n,e){await Bun.write(e,D(n))}async function z(n){let e=await Bun.file(n).text();return JSON.parse(e)}var x=[],m;function K(n,e){let r=m;m=n;try{e()}finally{m=r}}function U(n,e){x.push({groupName:m,name:n,fn:e})}function G(){return x}function Z(){x.length=0,m=void 0}function X(n){if(n.length===0)throw Error("computeTimingStats: samples must be non-empty");let e=n.length,r=b(n),t=0;for(let a=0;a<e;a++)t+=n[a];let i=t/e,o=g(r,0.5),s=0;for(let a=0;a<e;a++){let u=n[a]-i;s+=u*u}let p=Math.sqrt(s/e),y=r[0],f=r[e-1],h=g(r,0.25),w=g(r,0.75),l=w-h,v=h-1.5*l,W=w+1.5*l,S=h-3*l,F=w+3*l,R=0,T=0;for(let a=0;a<e;a++){let u=n[a];if(u<S||u>F)T++;else if(u<v||u>W)R++}return{unit:"ns",samples:n,mean:i,median:o,stddev:p,min:y,max:f,outliers:{mild:R,severe:T}}}function b(n){let e=new Float64Array(n.length);return e.set(n),e.sort(),e}function g(n,e){let r=n.length;if(r===1)return n[0];let t=e*(r-1),i=Math.floor(t),o=Math.ceil(t);if(i===o)return n[i];let s=t-i;return n[i]*(1-s)+n[o]*s}var I=5000000,A=200;function Y(n,e,r="subprocess"){let t=[],i=n.samples[0];if(i!==void 0){let s=b(n.samples),p=g(s,0.25),f=g(s,0.75)-p;if(i>n.median+3*f&&f>0)t.push({code:"slow-first-run",message:`First run took ${(i/1e6).toFixed(2)}ms, much slower than the median ${(n.median/1e6).toFixed(2)}ms. Consider more warmup.`,data:{firstNs:i,medianNs:n.median}})}if(n.outliers.mild+n.outliers.severe>0)t.push({code:"outliers-detected",message:`${n.outliers.mild+n.outliers.severe} outlier(s) detected (${n.outliers.severe} severe, ${n.outliers.mild} mild).`,data:n.outliers});if(r==="subprocess"&&n.median<I)t.push({code:"fast-command",message:`Median run time (${(n.median/1e6).toFixed(3)}ms) is very fast; results may be dominated by spawn overhead.`,data:{medianNs:n.median}});if(r==="inprocess"&&n.median<A)t.push({code:"below-timer-resolution",message:`Median run time (${n.median.toFixed(0)}ns) is close to timer resolution; consider a larger batch size or a coarser operation.`,data:{medianNs:n.median}});let o=e.filter((s)=>s!==void 0&&s!==0);if(o.length>0)t.push({code:"nonzero-exit",message:`${o.length} of ${e.length} trial(s) exited non-zero.`,data:{exitCodes:o}});return t}
4
+ export{N as i,c as j,k,E as l,O as m,C as n,q as o,_ as p,H as q,J as r,j as s,D as t,L as u,z as v,X as w,Y as x,K as y,U as z,G as A,Z as B};
@@ -0,0 +1,19 @@
1
+ // @bun
2
+ import{i as z,j as k,l as E,m as $e,n as Ce,p as Ie,q as j,r as Ne,s as G,t as pe,v as H,w as re,x as se}from"./chunk-ck12vbed.js";function Ue(e){return e.startsWith("file://")?e.slice(7):e}function W(e,a,n){let s=e.nodes,t=s.length,i=new Map,o=[],r=new Map,c=new Int32Array(t);for(let m=0;m<t;m++){let d=s[m],u=d.callFrame,y=Ue(u.url),T=i.get(u.functionName);if(T===void 0)T=new Map,i.set(u.functionName,T);let I=T.get(y);if(I===void 0)I=o.length,T.set(y,I),o.push({key:k("fr",u.functionName,y),name:u.functionName,url:y||void 0,line:u.lineNumber>=0?u.lineNumber:void 0,col:u.columnNumber>=0?u.columnNumber:void 0});c[m]=I,r.set(d.id,m)}let f=Array(t);for(let m=0;m<t;m++){let d=s[m];f[m]={id:d.id,frameIx:c[r.get(d.id)],children:d.children??[]}}let p=new Float64Array(t),l=new Float64Array(t),g=e.samples,x=e.timeDeltas;for(let m=0;m<g.length;m++){let d=r.get(g[m]);if(d===void 0)continue;p[d]+=x[m]??0,l[d]+=1}let R=new Int32Array(t).fill(-1);for(let m=0;m<t;m++){let d=s[m].children;if(!d)continue;for(let u of d){let y=r.get(u);if(y!==void 0)R[y]=m}}let h=[],w=[];for(let m=t-1;m>=0;m--)if(R[m]===-1)w.push(m);while(w.length>0){let m=w.pop();h.push(m);let d=s[m].children;if(!d)continue;for(let u of d){let y=r.get(u);if(y!==void 0&&R[y]===m)w.push(y)}}let P=new Float64Array(t);for(let m=h.length-1;m>=0;m--){let d=h[m];P[d]+=p[d];let u=R[d];if(u>=0)P[u]+=P[d]}let C=Array(o.length),b=[];for(let m=0;m<t;m++){let d=f[m].frameIx,u=C[d];if(u)u.selfUs+=p[m],u.totalUs+=P[m],u.samples+=l[m];else{let y={frameIx:d,selfUs:p[m],totalUs:P[m],samples:l[m]};C[d]=y,b.push(y)}}return{origin:a,samplingIntervalUs:n,frames:o,nodes:f,totals:b.sort((m,d)=>d.selfUs-m.selfUs),samples:{nodeIds:e.samples,timeDeltasUs:e.timeDeltas}}}function ve(e,a,n,s){let t=["--cpu-prof","--cpu-prof-dir",a,"--cpu-prof-name",n,"--cpu-prof-interval",String(s)],i=e[0];if(i==="bun"||i?.endsWith("/bun"))return[i,...t,...e.slice(1)];return e}async function Y(e){let a=`${e.artifactDir}/${e.fileName}`,n=e.argv[0],s=n==="bun"||n?.endsWith("/bun"),t=ve(e.argv,e.artifactDir,e.fileName,e.intervalUs),i=s?e.env:{...process.env,...e.env,BUN_OPTIONS:`--cpu-prof --cpu-prof-dir ${e.artifactDir} --cpu-prof-name ${e.fileName} --cpu-prof-interval ${e.intervalUs}`},o=Bun.nanoseconds(),c=await Bun.spawn(t,{cwd:e.cwd,env:i,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,f=Bun.nanoseconds()-o,p=Bun.file(a);if(!await p.exists())return{diagnosticWallNs:f,exitCode:c,warnings:[{code:"artifact-missing",message:`Expected a .cpuprofile at ${a} after exit ${c}, found nothing. The workload's argv[0] must be a \`bun\` binary for CPU capture.`,data:{artifactPath:a,argv:e.argv}}]};let l=await p.json(),g=W(l,"cpu-prof",e.intervalUs),x=l.samples.length===0?[{code:"empty-profile",message:"CPU capture produced zero samples."}]:[];return{diagnosticWallNs:f,exitCode:c,artifactPath:a,cpu:g,warnings:x}}function q(e,a="heap-prof"){let{node_fields:n,node_types:s}=e.snapshot.meta,t=n.indexOf("type"),i=n.indexOf("self_size"),o=n.length,r=s[0];if(t===-1||i===-1||!Array.isArray(r))return{origin:a,typeCounts:[],objectCount:e.snapshot.node_count};let c=r.length,f=Array(c),p=new Map,l=[],g=0,x=e.nodes,R=x.length;for(let b=0;b<R;b+=o){let m=x[b+t],d=x[b+i]??0;g+=d;let u;if(m>=0&&m<c){if(u=f[m],u===void 0)u={type:r[m],count:0,bytes:0},f[m]=u,l.push(u)}else{let y=`unknown(${m})`;if(u=p.get(y),u===void 0)u={type:y,count:0,bytes:0},p.set(y,u),l.push(u)}u.count++,u.bytes+=d}let h=l.sort((b,m)=>m.count-b.count),w=h.slice(0,20),P=h.slice(20),C=w.map(({type:b,count:m,bytes:d})=>({type:b,count:m,retainedBytes:d}));if(P.length>0){let b=0,m=0;for(let d of P)b+=d.count,m+=d.bytes;C.push({type:"other",count:b,retainedBytes:m})}return{origin:a,heapSizeBytes:g,objectCount:e.snapshot.node_count,typeCounts:C}}function ke(e,a,n){let s=["--heap-prof","--heap-prof-dir",a,"--heap-prof-name",n],t=e[0];if(t==="bun"||t?.endsWith("/bun"))return[t,...s,...e.slice(1)];return e}async function Q(e){let a=`${e.artifactDir}/${e.fileName}`,n=e.argv[0],s=n==="bun"||n?.endsWith("/bun"),t=ke(e.argv,e.artifactDir,e.fileName),i=s?e.env:{...process.env,...e.env,BUN_OPTIONS:`--heap-prof --heap-prof-dir ${e.artifactDir} --heap-prof-name ${e.fileName}`},o=Bun.nanoseconds(),c=await Bun.spawn(t,{cwd:e.cwd,env:i,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,f=Bun.nanoseconds()-o,p=Bun.file(a);if(!await p.exists())return{diagnosticWallNs:f,exitCode:c,warnings:[{code:"artifact-missing",message:`Expected a heap snapshot at ${a} after exit ${c}, found nothing. The workload's argv[0] must be a \`bun\` binary for heap capture.`,data:{artifactPath:a,argv:e.argv}}]};let l=await p.json(),g=q(l,"heap-prof");return{diagnosticWallNs:f,exitCode:c,artifactPath:a,heap:g,warnings:[]}}import{Session as Fe}from"inspector/promises";var De=1000;async function X(e,a={}){let n=a.intervalUs??De,s=new Fe;s.connect();let t=Bun.nanoseconds();try{await s.post("Profiler.enable"),await s.post("Profiler.setSamplingInterval",{interval:n}),await s.post("Profiler.start");let i=await e(),{profile:o}=await s.post("Profiler.stop"),r=Bun.nanoseconds()-t,c=W(o,"inspector",n);return{result:i,cpu:c,diagnosticWallNs:r}}finally{s.disconnect()}}import{profile as Se}from"bun:jsc";var Me=new Map([["LLInt","llint"],["Baseline","baseline"],["DFG","dfg"],["FTL","ftl"]]),Z=4294967295;function ee(e,a){let n=a??e.interval*1e6,s=new Map,t=[];function i(u,y,T,I){let U=s.get(u);if(U===void 0)U=new Map,s.set(u,U);let N=y??"",v=U.get(N);if(v===void 0)v=t.length,U.set(N,v),t.push({key:k("fr",u,N),name:u,url:y,line:T,col:I});return v}function o(u){let y=u.line===Z,T=y?void 0:u.line-1,I=y||u.column===Z?void 0:u.column-1;return i(u.name,u.sourceURL,T,I)}let r=i("(root)",void 0,void 0,void 0),c=1,f={id:0,frameIx:r,children:new Map,selfUs:0,samples:0,totalUs:0},p=new Map([[0,f]]),l={llint:0,baseline:0,dfg:0,ftl:0},g=new Map,x=[],R=[];for(let u of e.traces){let y=u.frames,T=f;for(let N=y.length-1;N>=0;N--){let v=o(y[N]),M=T.children.get(v);if(!M)M={id:c++,frameIx:v,children:new Map,selfUs:0,samples:0,totalUs:0},T.children.set(v,M),p.set(M.id,M);T=M}T.selfUs+=n,T.samples+=1,x.push(T.id),R.push(n);let I=y[0],U=I&&Me.get(I.category);if(U){l[U]++;let N=g.get(U)??new Map;N.set(T.frameIx,(N.get(T.frameIx)??0)+1),g.set(U,N)}}function h(u){let y=u.selfUs;for(let T of u.children.values())y+=h(T);return u.totalUs=y,y}h(f);let w=new Map;function P(u){let y=w.get(u.frameIx);if(y)y.selfUs+=u.selfUs,y.totalUs+=u.totalUs,y.samples+=u.samples;else w.set(u.frameIx,{frameIx:u.frameIx,selfUs:u.selfUs,totalUs:u.totalUs,samples:u.samples});for(let T of u.children.values())P(T)}P(f);let C=[...p.values()].map((u)=>({id:u.id,frameIx:u.frameIx,children:[...u.children.values()].map((y)=>y.id)})),b={origin:"jsc-profile",samplingIntervalUs:n,frames:t,nodes:C,totals:[...w.values()].sort((u,y)=>y.selfUs-u.selfUs),samples:{nodeIds:x,timeDeltasUs:R}},m=[...g.entries()].flatMap(([u,y])=>[...y.entries()].sort((T,I)=>I[1]-T[1]).slice(0,3).map(([T,I])=>({tier:u,frameKey:t[T].key,samples:I})));return{cpu:b,jit:{origin:"jsc-profile",tiers:l,topFramesByTier:m}}}var Be=1000;async function ne(e,a={}){let n=a.intervalUs??Be,s,t=Bun.nanoseconds(),i=await Se(async()=>(s=await e(),s),n),o=Bun.nanoseconds()-t,{cpu:r,jit:c}=ee(i.stackTraces,n);return{result:s,cpu:r,jit:c,diagnosticWallNs:o}}async function L(e){let a=Bun.nanoseconds(),n=Bun.spawn(e.argv,{cwd:e.cwd,env:e.env,stdout:"ignore",stderr:"ignore",stdin:"ignore"}),s=await n.exited,t=Bun.nanoseconds(),i=n.resourceUsage?.();return{wallNs:t-a,exitCode:s,userNs:i?Number(i.cpuTime.user)*1000:void 0,systemNs:i?Number(i.cpuTime.system)*1000:void 0,maxRssBytes:i?.maxRSS}}function te(e){return e.trim().split(/\s+/).filter(Boolean)}var Oe=10,We=3000000000,Ee=3;async function oe(e){let a=e.warmup??Ee;for(let p=0;p<a;p++)await L(e);let n=[],s=e.runs??e.minRuns??Oe,t=e.runs!==void 0?0:e.minTotalNs??We,i=0,o=0;while(o<s||i<t){let p=await L(e);if(n.push({i:o,wallNs:p.wallNs,exitCode:p.exitCode,userNs:p.userNs,systemNs:p.systemNs,maxRssBytes:p.maxRssBytes}),i+=p.wallNs,o++,e.runs!==void 0&&o>=e.runs)break}let r=n.map((p)=>p.wallNs),c=re(r),f=se(c,n.map((p)=>p.exitCode));return{trials:n,timing:c,warnings:f}}var Ae=new URL("./runner.ts",import.meta.url).pathname,_e=".ostia";async function je(e){let n=`${e.outDir??_e}/bench-tmp`,s=e.cwd??process.cwd(),t={timeBudgetMs:e.timeBudgetMs,minSamples:e.minSamples,gc:e.gc},i=[],o=[];try{for(let r of e.suites){let c=r.startsWith("/")?r:`${s}/${r}`,f=`${n}/${k("bench-out",c)}.json`,l=await Bun.spawn(["bun",Ae,c,f,JSON.stringify(t)],{cwd:s,stdout:"inherit",stderr:"inherit",stdin:"ignore"}).exited;if(l!==0)throw Error(`Bench suite failed: ${r} (runner exited ${l})`);let g=await H(f);i.push(...g.workloads),o.push(...g.runs)}}finally{await Bun.spawn(["rm","-rf",n]).exited}return E(i,o)}var ie={timingPct:5,frameSelfPct:10,heapTypePct:10,minFrameSelfUs:1000};function A(e,a){if(e===0)return a===0?0:1/0;return(a-e)/e*100}function S(e,a,n){return e.runs.find((s)=>s.workloadId===a&&s.phase===n)}function Le(e,a,n=ie){let s=new Set(a.workloads.map((i)=>i.id)),t=[];for(let i of e.workloads){if(!s.has(i.id))continue;let o=He(e,a,i.id,n);if(o)t.push(o)}return t}function He(e,a,n,s=ie){let t=S(e,n,"timing"),i=S(a,n,"timing"),o=S(e,n,"cpu"),r=S(a,n,"cpu"),c=S(e,n,"heap"),f=S(a,n,"heap"),p=t?.id??o?.id??c?.id,l=i?.id??r?.id??f?.id;if(!p||!l)return;let g=!1,x;if(t?.timing&&i?.timing){let w=A(t.timing.median,i.timing.median),P=A(t.timing.mean,i.timing.mean),C=w>s.timingPct?"regressed":w<-s.timingPct?"improved":"unchanged";if(C==="regressed")g=!0;x={medianDeltaPct:w,meanDeltaPct:P,verdict:C}}let R;if(o?.cpu&&r?.cpu){let w=new Map(o.cpu.totals.map((d)=>[o.cpu.frames[d.frameIx].key,d])),P=new Map(r.cpu.totals.map((d)=>[r.cpu.frames[d.frameIx].key,d])),C=new Map(o.cpu.frames.map((d)=>[d.key,d.name])),b=new Map(r.cpu.frames.map((d)=>[d.key,d.name]));R=[...new Set([...w.keys(),...P.keys()])].map((d)=>{let u=w.get(d)?.selfUs??0,y=P.get(d)?.selfUs??0;return{frameKey:d,name:b.get(d)??C.get(d)??d,baseSelfUs:u,candSelfUs:y,deltaPct:A(u,y)}}).sort((d,u)=>Math.abs(u.deltaPct)-Math.abs(d.deltaPct));for(let d of R)if((d.baseSelfUs>=s.minFrameSelfUs||d.candSelfUs>=s.minFrameSelfUs)&&d.deltaPct>s.frameSelfPct)g=!0}let h;if(c?.heap&&f?.heap){let w=new Map(c.heap.typeCounts.map((b)=>[b.type,b])),P=new Map(f.heap.typeCounts.map((b)=>[b.type,b]));h=[...new Set([...w.keys(),...P.keys()])].map((b)=>{let m=w.get(b),d=P.get(b);return{type:b,baseCount:m?.count??0,candCount:d?.count??0,baseBytes:m?.retainedBytes,candBytes:d?.retainedBytes,deltaPct:A(m?.count??0,d?.count??0)}}).sort((b,m)=>Math.abs(m.deltaPct)-Math.abs(b.deltaPct));for(let b of h)if(b.deltaPct>s.heapTypePct)g=!0}return{id:k("cmp",p,l),baselineRunId:p,candidateRunId:l,timing:x,frames:R,heapTypes:h,thresholds:s,verdict:g?"fail":"pass"}}function F(e,a){if(a){let n=e.runs.find((s)=>s.id===a);return n?.cpu?[n]:[]}return e.runs.filter((n)=>n.phase==="cpu"&&n.cpu)}function B(e){let a=e.nodes,n=a.length,s=ze(e),t=new Int32Array(n).fill(-1);for(let c=0;c<n;c++)for(let f of a[c].children){let p=s(f);if(p!==-1)t[p]=c}let i=[];for(let c=0;c<n;c++)if(t[c]===-1)i.push(c);let o=[],r=[];for(let c=i.length-1;c>=0;c--)r.push(i[c]);while(r.length>0){let c=r.pop();o.push(c);for(let f of a[c].children){let p=s(f);if(p!==-1&&t[p]===c)r.push(p)}}return{count:n,indexOf:s,parentIx:t,roots:i,order:o}}function ze(e){let a=e.nodes,n=a.length,s=1/0,t=-1/0,i=!0;for(let r=0;r<n;r++){let c=a[r].id;if(!Number.isInteger(c)){i=!1;break}if(c<s)s=c;if(c>t)t=c}if(i&&n>0&&t-s<n*4+64){let r=t-s+1,c=new Int32Array(r).fill(-1);for(let f=0;f<n;f++)c[a[f].id-s]=f;return(f)=>{let p=f-s;return p>=0&&p<r?c[p]:-1}}let o=new Map;for(let r=0;r<n;r++)o.set(a[r].id,r);return(r)=>o.get(r)??-1}function ae(e,a){let{count:n,indexOf:s,parentIx:t,order:i}=a,o=new Float64Array(n),r=new Float64Array(n),c=e.samples?.nodeIds??[],f=e.samples?.timeDeltasUs??[];for(let l=0;l<c.length;l++){let g=s(c[l]);if(g===-1)continue;o[g]+=f[l]??0,r[g]+=1}let p=new Float64Array(n);for(let l=i.length-1;l>=0;l--){let g=i[l];p[g]+=o[g];let x=t[g];if(x>=0)p[x]+=p[g]}return{selfUs:o,totalUs:p,samples:r}}var ce={name:"collapsed",async render(e,a={}){return{files:F(e,a.runId).map((t)=>{let i=t.cpu,{nodes:o,frames:r}=i,c=B(i),f=Array(c.count);for(let R of c.order){let h=r[o[R].frameIx].name||"(anonymous)",w=c.parentIx[R];f[R]=w===-1?h:`${f[w]};${h}`}let p=new Float64Array(c.count),l=[],g=i.samples?.nodeIds??[];for(let R=0;R<g.length;R++){let h=c.indexOf(g[R]);if(h===-1)continue;if(p[h]++===0)l.push(h)}let x=Array(l.length);for(let R=0;R<l.length;R++){let h=l[R];x[R]=`${f[h]} ${p[h]}`}return{path:`${t.id}.collapsed.txt`,content:x.join(`
3
+ `)+(x.length>0?`
4
+ `:"")}})}}};var ue={name:"cpuprofile",async render(e,a={}){let n=F(e,a.runId),s=[],t=[];for(let i of n){if(i.cpu?.origin!=="cpu-prof"&&i.cpu?.origin!=="inspector"){t.push(`${i.id} (origin ${i.cpu?.origin??"unknown"} has no .cpuprofile artifact to pass through)`);continue}let o=i.artifacts.find((c)=>c.kind==="cpuprofile");if(!o){t.push(`${i.id} (no cpuprofile artifact recorded on this run)`);continue}let r=Bun.file(o.path);if(!await r.exists()){t.push(`${i.id} (artifact missing on disk: ${o.path})`);continue}s.push({path:`${i.id}.cpuprofile`,content:await r.text()})}if(s.length===0&&t.length>0)return{text:`No .cpuprofile artifacts available:
5
+ ${t.map((i)=>` - ${i}`).join(`
6
+ `)}
7
+ `};return{files:s}}};var le={name:"json",async render(e){return{text:pe(e)}}};var me={name:"jsonl",async render(e){let{runs:a,...n}=e;return{text:`${[z(n),...a.map((t)=>z(t))].join(`
8
+ `)}
9
+ `}}};function D(e){return(e/1e6).toFixed(3)}function _(e){return e?.label??e?.command?.join(" ")??e?.entry?.task??e?.id??"unknown"}var fe=10,de=10,ge={name:"markdown",async render(e){let a=new Map(e.workloads.map((t)=>[t.id,t])),n=[];n.push("# Profile Report",""),n.push(`Bun ${e.bunVersion} \xB7 ostia ${e.toolVersion} \xB7 ${e.platform.os}/${e.platform.arch} \xB7 ${e.createdAt}`,"");let s=e.runs.filter((t)=>t.phase==="timing"&&t.timing!==void 0);if(s.length>0){n.push("## Timing",""),n.push("| Command | Mean \xB1 SD (ms) | Min\u2026Max (ms) | Median (ms) |","|---|---|---|---|");for(let i of s){let o=_(a.get(i.workloadId)),r=i.timing;n.push(`| ${o} | ${D(r.mean)} \xB1 ${D(r.stddev)} | ${D(r.min)}\u2026${D(r.max)} | ${D(r.median)} |`)}n.push("");let t=s.filter((i)=>i.warnings.length>0);if(t.length>0){n.push("### Warnings","");for(let i of t){let o=_(a.get(i.workloadId));for(let r of i.warnings)n.push(`- **${o}**: ${r.message} (\`${r.code}\`)`)}n.push("")}}for(let t of e.runs){if(t.phase!=="cpu"&&t.phase!=="heap")continue;let i=_(a.get(t.workloadId));if(t.phase==="cpu"){if(n.push(`## CPU capture - ${i}`,""),n.push(`instrumented, diagnostic wall ${D(t.diagnosticWallNs??0)}ms`,""),t.cpu){n.push(`origin: \`${t.cpu.origin}\`, interval: ${t.cpu.samplingIntervalUs}\xB5s`,""),n.push("| Self % | Self (ms) | Total (ms) | Frame |","|---|---|---|---|");let o=t.cpu.totals.reduce((r,c)=>r+c.selfUs,0)||1;for(let r of t.cpu.totals.slice(0,fe)){let c=t.cpu.frames[r.frameIx],f=(r.selfUs/o*100).toFixed(1);n.push(`| ${f}% | ${(r.selfUs/1000).toFixed(2)} | ${(r.totalUs/1000).toFixed(2)} | ${c?.name||"(anonymous)"} |`)}if(n.push(""),t.jit){let r=t.jit.tiers;n.push(`JIT tiers: LLInt ${r.llint} \xB7 Baseline ${r.baseline} \xB7 DFG ${r.dfg} \xB7 FTL ${r.ftl}`,"")}}}else if(n.push(`## Heap snapshot - ${i}`,""),n.push(`instrumented, diagnostic wall ${D(t.diagnosticWallNs??0)}ms`,""),t.heap){n.push(`${t.heap.objectCount??"?"} objects, ${((t.heap.heapSizeBytes??0)/1e6).toFixed(2)}MB`,""),n.push("| Count | Type |","|---|---|");for(let o of t.heap.typeCounts.slice(0,de))n.push(`| ${o.count} | ${o.type} |`);n.push("")}for(let o of t.artifacts)n.push(`- artifact: \`${o.path}\``);for(let o of t.warnings)n.push(`- ! ${o.message} (\`${o.code}\`)`);if(t.artifacts.length>0||t.warnings.length>0)n.push("")}if(e.comparisons&&e.comparisons.length>0){n.push("## Comparisons","");for(let t of e.comparisons){let i=e.runs.find((r)=>r.id===t.candidateRunId),o=_(i?a.get(i.workloadId):void 0);if(n.push(`### ${t.verdict==="pass"?"\u2713":"\u2717"} ${o}`,""),t.timing){let r=t.timing.medianDeltaPct>0?"+":"";n.push(`- timing: ${r}${t.timing.medianDeltaPct.toFixed(1)}% median (**${t.timing.verdict}**)`)}for(let r of t.frames?.slice(0,fe)??[]){if(Math.abs(r.deltaPct)<0.5)continue;let c=r.deltaPct>0?"+":"";n.push(`- frame \`${r.name}\`: ${c}${r.deltaPct.toFixed(1)}% self-time (${(r.baseSelfUs/1000).toFixed(2)}ms \u2192 ${(r.candSelfUs/1000).toFixed(2)}ms)`)}for(let r of t.heapTypes?.slice(0,de)??[]){if(Math.abs(r.deltaPct)<0.5)continue;let c=r.deltaPct>0?"+":"";n.push(`- heap \`${r.type}\`: ${c}${r.deltaPct.toFixed(1)}% count (${r.baseCount} \u2192 ${r.candCount})`)}n.push("")}}return{text:n.join(`
10
+ `)}}};var Je=15;function J(e){return`n${e}`}function Ve(e,a,n){return`${(e||"(anonymous)").replace(/"/g,"'")} (self ${(a/1000).toFixed(2)}ms, total ${(n/1000).toFixed(2)}ms)`}function Ke(e,a,n,s){let t=[];if(s<=0)return t;for(let i=0;i<a;i++){if(i===n)continue;let o=e[i];if(t.length===s&&o<=e[t[s-1]])continue;let r=t.length;while(r>0&&e[t[r-1]]<o)r--;if(t.splice(r,0,i),t.length>s)t.pop()}return t}var he={name:"mermaid",async render(e,a={}){let n=a.topN??Je;return{files:F(e,a.runId).map((i)=>{let o=i.cpu,{nodes:r,frames:c}=o,f=B(o),{selfUs:p,totalUs:l}=ae(o,f),{parentIx:g}=f,x=f.roots[0]??-1,R=Ke(p,f.count,x,n),h=new Set(x!==-1?[x]:[]),w=[];for(let C of R){w.length=0;for(let b=C;b!==-1;b=g[b])w.push(b);for(let b=w.length-1;b>=0;b--)h.add(w[b])}let P=["graph TD"];for(let C of h){let b=r[C].id;P.push(` ${J(b)}["${Ve(c[r[C].frameIx].name,p[C],l[C])}"]`)}for(let C of h){let b=g[C];if(b!==-1&&h.has(b))P.push(` ${J(r[b].id)} --> ${J(r[C].id)}`)}return{path:`${i.id}.mermaid.md`,content:`${P.join(`
11
+ `)}
12
+ `}})}}};var Ge="https://www.speedscope.app/file-format-schema.json";function be(e){return e?.label??e?.command?.join(" ")??e?.entry?.task??"profile"}var ye={name:"speedscope",async render(e,a={}){let n=F(e,a.runId),s=new Map(e.workloads.map((i)=>[i.id,i]));return{files:n.map((i)=>{let o=i.cpu,{nodes:r}=o,c=B(o),f=o.samples?.nodeIds??[],p=o.samples?.timeDeltasUs??[],l=Array(c.count);for(let h of c.order){let w=c.parentIx[h],P=r[h].frameIx;l[h]=w===-1?[P]:[...l[w],P]}let g=Array(f.length);for(let h=0;h<f.length;h++){let w=c.indexOf(f[h]);g[h]=w===-1?[]:l[w]}let x=0;for(let h=0;h<p.length;h++)x+=p[h];let R={$schema:Ge,exporter:"ostia",name:be(s.get(i.workloadId)),activeProfileIndex:0,shared:{frames:o.frames.map((h)=>({name:h.name||"(anonymous)",file:h.url,line:h.line!==void 0?h.line+1:void 0}))},profiles:[{type:"sampled",name:be(s.get(i.workloadId)),unit:"microseconds",startValue:0,endValue:x,samples:g,weights:p}]};return{path:`${i.id}.speedscope.json`,content:`${JSON.stringify(R,null,2)}
13
+ `}})}}};function O(e){return(e/1e6).toFixed(3)}function V(e){return e.label??e.command?.join(" ")??e.entry?.task??e.id}var xe={name:"table",async render(e){let a=e.runs.filter((l)=>l.phase==="timing"&&l.timing!==void 0),n=new Map(e.workloads.map((l)=>[l.id,l]));if(a.length===0){let l=we(e,n);return{text:l.length>0?`${l.join(`
14
+ `)}
15
+ `:`(no timing runs)
16
+ `}}let s=a.map((l)=>{let g=n.get(l.workloadId);return{run:l,workload:g,label:g?V(g):l.workloadId}}),t=Math.min(...s.map((l)=>l.run.timing.median)),i=s.length>1,o=[],r=Math.max(7,...s.map((l)=>l.label.length)),c=i?`${"Command".padEnd(r)} Mean [ms] Min\u2026Max [ms] Relative`:`${"Command".padEnd(r)} Mean [ms] Min\u2026Max [ms]`;o.push(c),o.push("-".repeat(c.length));for(let{run:l,label:g}of s){let x=l.timing,R=`${O(x.mean)} \xB1 ${O(x.stddev)}`,h=`${O(x.min)}\u2026${O(x.max)}`,w=`${g.padEnd(r)} ${R.padEnd(15)} ${h.padEnd(18)}`;if(i){let P=x.median/t;w+=P===1?" 1.00\xD7":` ${P.toFixed(2)}\xD7 slower`}o.push(w);for(let P of l.warnings)o.push(` ! ${P.message}`)}let f=qe(e,n);if(f.length>0)o.push(""),o.push(...f);let p=we(e,n);if(p.length>0)o.push(""),o.push(...p);return{text:`${o.join(`
17
+ `)}
18
+ `}}};function Ye(e,a,n){let s=e.runs.find((i)=>i.id===n),t=s?a.get(s.workloadId):void 0;return t?V(t):n}function we(e,a){if(!e.comparisons||e.comparisons.length===0)return[];let n=[];for(let s of e.comparisons){let t=Ye(e,a,s.candidateRunId),i=s.verdict==="pass"?"\u2713":"\u2717";if(n.push(`${i} ${t}`),s.timing){let o=s.timing.medianDeltaPct>0?"+":"";n.push(` timing: ${o}${s.timing.medianDeltaPct.toFixed(1)}% median (${s.timing.verdict})`)}if(s.frames)for(let o of s.frames.slice(0,Re)){if(Math.abs(o.deltaPct)<0.5)continue;let r=o.deltaPct>0?"+":"";n.push(` frame ${o.name}: ${r}${o.deltaPct.toFixed(1)}% self-time (${(o.baseSelfUs/1000).toFixed(2)}ms -> ${(o.candSelfUs/1000).toFixed(2)}ms)`)}if(s.heapTypes)for(let o of s.heapTypes.slice(0,Pe)){if(Math.abs(o.deltaPct)<0.5)continue;let r=o.deltaPct>0?"+":"";n.push(` heap ${o.type}: ${r}${o.deltaPct.toFixed(1)}% count (${o.baseCount} -> ${o.candCount})`)}}return n}var Re=5,Pe=5;function qe(e,a){let n=[];for(let s of e.runs){if(s.phase!=="cpu"&&s.phase!=="heap")continue;let t=a.get(s.workloadId),i=t?V(t):s.workloadId;if(s.phase==="cpu")if(s.cpu){n.push(`CPU capture - ${i} (instrumented, ${s.cpu.samplingIntervalUs}\xB5s interval, diagnostic wall ${O(s.diagnosticWallNs??0)}ms)`);let o=s.cpu.totals.reduce((r,c)=>r+c.selfUs,0)||1;for(let r of s.cpu.totals.slice(0,Re)){let c=s.cpu.frames[r.frameIx],f=(r.selfUs/o*100).toFixed(1);n.push(` ${f.padStart(5)}% ${(r.selfUs/1000).toFixed(2).padStart(8)}ms self ${c?.name??"?"}`)}}else n.push(`CPU capture - ${i} (instrumented, no evidence captured)`);else if(s.heap){let o=((s.heap.heapSizeBytes??0)/1e6).toFixed(2);n.push(`Heap snapshot - ${i} (instrumented, ${s.heap.objectCount??"?"} objects, ${o}MB)`);for(let r of s.heap.typeCounts.slice(0,Pe))n.push(` ${String(r.count).padStart(6)} ${r.type}`)}else n.push(`Heap snapshot - ${i} (instrumented, no evidence captured)`);for(let o of s.artifacts)n.push(` artifact: ${o.path}`);for(let o of s.warnings)n.push(` ! ${o.message}`)}return n}var Qe={table:xe,json:le,markdown:ge,jsonl:me,collapsed:ce,mermaid:he,speedscope:ye,cpuprofile:ue};var Xe=".ostia",K=1000;async function st(e){let a=G({runs:e.runs??null,warmup:e.warmup??null,cpu:e.cpu??!1,heap:e.heap??!1,cpuIntervalUs:e.cpuIntervalUs??K}),s=`${e.outDir??Xe}/artifacts`,t=[],i=[];for(let o of e.commands){let r=Array.isArray(o)?o:te(o),c=$e(r,Array.isArray(o)?void 0:o);t.push(c);let f=await oe({argv:r,cwd:e.cwd,env:e.env,runs:e.runs,warmup:e.warmup}),p=Ie({workload:c,configFingerprint:a,trials:f.trials,timing:f.timing,warnings:f.warnings});if(i.push(p),e.cpu){let l=`${p.id}-cpu.cpuprofile`,g=await Y({argv:r,cwd:e.cwd,env:e.env,artifactDir:s,fileName:l,intervalUs:e.cpuIntervalUs??K});i.push(await Te({workload:c,phase:"cpu",configFingerprint:a,diagnosticWallNs:g.diagnosticWallNs,exitCode:g.exitCode,cpu:g.cpu,artifactPath:g.artifactPath,artifactKind:"cpuprofile",warnings:g.warnings}))}if(e.heap){let l=`${p.id}-heap.heapsnapshot`,g=await Q({argv:r,cwd:e.cwd,env:e.env,artifactDir:s,fileName:l});i.push(await Te({workload:c,phase:"heap",configFingerprint:a,diagnosticWallNs:g.diagnosticWallNs,exitCode:g.exitCode,heap:g.heap,artifactPath:g.artifactPath,artifactKind:"heapsnapshot",warnings:g.warnings}))}}return E(t,i)}async function Te(e){let a=`${e.workload.id}-${e.phase}-${e.configFingerprint}`,n=e.artifactPath?[await Ne(a,e.artifactKind,e.artifactPath)]:[];return j({workload:e.workload,phase:e.phase,configFingerprint:e.configFingerprint,diagnosticWallNs:e.diagnosticWallNs,exitCode:e.exitCode,cpu:e.cpu,heap:e.heap,warnings:e.warnings,artifacts:n})}async function ot(e,a={}){let n=Ce(e),s=G({intervalUs:a.intervalUs??K,origin:a.origin??"inspector"}),t=(f)=>f.samples?.nodeIds.length===0?[{code:"empty-profile",message:"In-process capture produced zero samples."}]:[];if(a.origin==="jsc"){let{result:f,cpu:p,jit:l,diagnosticWallNs:g}=await ne(e,a),x=j({workload:n,phase:"cpu",configFingerprint:s,diagnosticWallNs:g,cpu:p,jit:l,warnings:t(p),artifacts:[]});return{result:f,run:x}}let{result:i,cpu:o,diagnosticWallNs:r}=await X(e,a),c=j({workload:n,phase:"cpu",configFingerprint:s,diagnosticWallNs:r,cpu:o,warnings:t(o),artifacts:[]});return{result:i,run:c}}
19
+ export{je as a,ie as b,Le as c,He as d,oe as e,Qe as f,st as g,ot as h};
package/cli.js CHANGED
@@ -1,29 +1,12 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- function q(e){return JSON.stringify(W(e))}function W(e){if(Array.isArray(e))return e.map(W);if(e!==null&&typeof e==="object"){let n={};for(let t of Object.keys(e).sort())n[t]=W(e[t]);return n}return e}function T(e,...n){let t=Bun.CryptoHasher.hash("sha256",q(n),"hex");return`${e}_${t.slice(0,16)}`}function Ye(e){return e.startsWith("file://")?e.slice(7):e}function K(e,n,t){let s=e.nodes,r=s.length,o=new Map,i=[],a=new Map,c=new Int32Array(r);for(let m=0;m<r;m++){let g=s[m],f=g.callFrame,y=Ye(f.url),C=o.get(f.functionName);if(C===void 0)C=new Map,o.set(f.functionName,C);let N=C.get(y);if(N===void 0)N=i.length,C.set(y,N),i.push({key:T("fr",f.functionName,y),name:f.functionName,url:y||void 0,line:f.lineNumber>=0?f.lineNumber:void 0,col:f.columnNumber>=0?f.columnNumber:void 0});c[m]=N,a.set(g.id,m)}let l=Array(r);for(let m=0;m<r;m++){let g=s[m];l[m]={id:g.id,frameIx:c[a.get(g.id)],children:g.children??[]}}let u=new Float64Array(r),p=new Float64Array(r),d=e.samples,b=e.timeDeltas;for(let m=0;m<d.length;m++){let g=a.get(d[m]);if(g===void 0)continue;u[g]+=b[m]??0,p[g]+=1}let x=new Int32Array(r).fill(-1);for(let m=0;m<r;m++){let g=s[m].children;if(!g)continue;for(let f of g){let y=a.get(f);if(y!==void 0)x[y]=m}}let w=[],R=[];for(let m=r-1;m>=0;m--)if(x[m]===-1)R.push(m);while(R.length>0){let m=R.pop();w.push(m);let g=s[m].children;if(!g)continue;for(let f of g){let y=a.get(f);if(y!==void 0&&x[y]===m)R.push(y)}}let k=new Float64Array(r);for(let m=w.length-1;m>=0;m--){let g=w[m];k[g]+=u[g];let f=x[g];if(f>=0)k[f]+=k[g]}let P=Array(i.length),h=[];for(let m=0;m<r;m++){let g=l[m].frameIx,f=P[g];if(f)f.selfUs+=u[m],f.totalUs+=k[m],f.samples+=p[m];else{let y={frameIx:g,selfUs:u[m],totalUs:k[m],samples:p[m]};P[g]=y,h.push(y)}}return{origin:n,samplingIntervalUs:t,frames:i,nodes:l,totals:h.sort((m,g)=>g.selfUs-m.selfUs),samples:{nodeIds:e.samples,timeDeltasUs:e.timeDeltas}}}function Qe(e,n,t,s){let r=["--cpu-prof","--cpu-prof-dir",n,"--cpu-prof-name",t,"--cpu-prof-interval",String(s)],o=e[0];if(o==="bun"||o?.endsWith("/bun"))return[o,...r,...e.slice(1)];return e}async function pe(e){let n=`${e.artifactDir}/${e.fileName}`,t=e.argv[0],s=t==="bun"||t?.endsWith("/bun"),r=Qe(e.argv,e.artifactDir,e.fileName,e.intervalUs),o=s?e.env:{...process.env,...e.env,BUN_OPTIONS:`--cpu-prof --cpu-prof-dir ${e.artifactDir} --cpu-prof-name ${e.fileName} --cpu-prof-interval ${e.intervalUs}`},i=Bun.nanoseconds(),c=await Bun.spawn(r,{cwd:e.cwd,env:o,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,l=Bun.nanoseconds()-i,u=Bun.file(n);if(!await u.exists())return{diagnosticWallNs:l,exitCode:c,warnings:[{code:"artifact-missing",message:`Expected a .cpuprofile at ${n} after exit ${c}, found nothing. The workload's argv[0] must be a \`bun\` binary for CPU capture.`,data:{artifactPath:n,argv:e.argv}}]};let p=await u.json(),d=K(p,"cpu-prof",e.intervalUs),b=p.samples.length===0?[{code:"empty-profile",message:"CPU capture produced zero samples."}]:[];return{diagnosticWallNs:l,exitCode:c,artifactPath:n,cpu:d,warnings:b}}function me(e,n="heap-prof"){let{node_fields:t,node_types:s}=e.snapshot.meta,r=t.indexOf("type"),o=t.indexOf("self_size"),i=t.length,a=s[0];if(r===-1||o===-1||!Array.isArray(a))return{origin:n,typeCounts:[],objectCount:e.snapshot.node_count};let c=a.length,l=Array(c),u=new Map,p=[],d=0,b=e.nodes,x=b.length;for(let h=0;h<x;h+=i){let m=b[h+r],g=b[h+o]??0;d+=g;let f;if(m>=0&&m<c){if(f=l[m],f===void 0)f={type:a[m],count:0,bytes:0},l[m]=f,p.push(f)}else{let y=`unknown(${m})`;if(f=u.get(y),f===void 0)f={type:y,count:0,bytes:0},u.set(y,f),p.push(f)}f.count++,f.bytes+=g}let w=p.sort((h,m)=>m.count-h.count),R=w.slice(0,20),k=w.slice(20),P=R.map(({type:h,count:m,bytes:g})=>({type:h,count:m,retainedBytes:g}));if(k.length>0){let h=0,m=0;for(let g of k)h+=g.count,m+=g.bytes;P.push({type:"other",count:h,retainedBytes:m})}return{origin:n,heapSizeBytes:d,objectCount:e.snapshot.node_count,typeCounts:P}}function Xe(e,n,t){let s=["--heap-prof","--heap-prof-dir",n,"--heap-prof-name",t],r=e[0];if(r==="bun"||r?.endsWith("/bun"))return[r,...s,...e.slice(1)];return e}async function de(e){let n=`${e.artifactDir}/${e.fileName}`,t=e.argv[0],s=t==="bun"||t?.endsWith("/bun"),r=Xe(e.argv,e.artifactDir,e.fileName),o=s?e.env:{...process.env,...e.env,BUN_OPTIONS:`--heap-prof --heap-prof-dir ${e.artifactDir} --heap-prof-name ${e.fileName}`},i=Bun.nanoseconds(),c=await Bun.spawn(r,{cwd:e.cwd,env:o,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,l=Bun.nanoseconds()-i,u=Bun.file(n);if(!await u.exists())return{diagnosticWallNs:l,exitCode:c,warnings:[{code:"artifact-missing",message:`Expected a heap snapshot at ${n} after exit ${c}, found nothing. The workload's argv[0] must be a \`bun\` binary for heap capture.`,data:{artifactPath:n,argv:e.argv}}]};let p=await u.json(),d=me(p,"heap-prof");return{diagnosticWallNs:l,exitCode:c,artifactPath:n,heap:d,warnings:[]}}import{Session as en}from"inspector/promises";var nn=1000;async function fe(e,n={}){let t=n.intervalUs??nn,s=new en;s.connect();let r=Bun.nanoseconds();try{await s.post("Profiler.enable"),await s.post("Profiler.setSamplingInterval",{interval:t}),await s.post("Profiler.start");let o=await e(),{profile:i}=await s.post("Profiler.stop"),a=Bun.nanoseconds()-r,c=K(i,"inspector",t);return{result:o,cpu:c,diagnosticWallNs:a}}finally{s.disconnect()}}import{profile as rn}from"bun:jsc";var tn=new Map([["LLInt","llint"],["Baseline","baseline"],["DFG","dfg"],["FTL","ftl"]]),ge=4294967295;function he(e,n){let t=n??e.interval*1e6,s=new Map,r=[];function o(f,y,C,N){let D=s.get(f);if(D===void 0)D=new Map,s.set(f,D);let F=y??"",U=D.get(F);if(U===void 0)U=r.length,D.set(F,U),r.push({key:T("fr",f,F),name:f,url:y,line:C,col:N});return U}function i(f){let y=f.line===ge,C=y?void 0:f.line-1,N=y||f.column===ge?void 0:f.column-1;return o(f.name,f.sourceURL,C,N)}let a=o("(root)",void 0,void 0,void 0),c=1,l={id:0,frameIx:a,children:new Map,selfUs:0,samples:0,totalUs:0},u=new Map([[0,l]]),p={llint:0,baseline:0,dfg:0,ftl:0},d=new Map,b=[],x=[];for(let f of e.traces){let y=f.frames,C=l;for(let F=y.length-1;F>=0;F--){let U=i(y[F]),A=C.children.get(U);if(!A)A={id:c++,frameIx:U,children:new Map,selfUs:0,samples:0,totalUs:0},C.children.set(U,A),u.set(A.id,A);C=A}C.selfUs+=t,C.samples+=1,b.push(C.id),x.push(t);let N=y[0],D=N&&tn.get(N.category);if(D){p[D]++;let F=d.get(D)??new Map;F.set(C.frameIx,(F.get(C.frameIx)??0)+1),d.set(D,F)}}function w(f){let y=f.selfUs;for(let C of f.children.values())y+=w(C);return f.totalUs=y,y}w(l);let R=new Map;function k(f){let y=R.get(f.frameIx);if(y)y.selfUs+=f.selfUs,y.totalUs+=f.totalUs,y.samples+=f.samples;else R.set(f.frameIx,{frameIx:f.frameIx,selfUs:f.selfUs,totalUs:f.totalUs,samples:f.samples});for(let C of f.children.values())k(C)}k(l);let P=[...u.values()].map((f)=>({id:f.id,frameIx:f.frameIx,children:[...f.children.values()].map((y)=>y.id)})),h={origin:"jsc-profile",samplingIntervalUs:t,frames:r,nodes:P,totals:[...R.values()].sort((f,y)=>y.selfUs-f.selfUs),samples:{nodeIds:b,timeDeltasUs:x}},m=[...d.entries()].flatMap(([f,y])=>[...y.entries()].sort((C,N)=>N[1]-C[1]).slice(0,3).map(([C,N])=>({tier:f,frameKey:r[C].key,samples:N})));return{cpu:h,jit:{origin:"jsc-profile",tiers:p,topFramesByTier:m}}}var sn=1000;async function be(e,n={}){let t=n.intervalUs??sn,s,r=Bun.nanoseconds(),o=await rn(async()=>(s=await e(),s),t),i=Bun.nanoseconds()-r,{cpu:a,jit:c}=he(o.stackTraces,t);return{result:s,cpu:a,jit:c,diagnosticWallNs:i}}var _="0.1.0";function M(e,n){return{schemaVersion:1,toolVersion:_,bunVersion:Bun.version,platform:{os:process.platform,arch:process.arch},createdAt:new Date().toISOString(),workloads:e,runs:n}}function G(e,n){return{id:T("wl","subprocess",e,process.cwd()),kind:"subprocess",command:e,label:n}}function we(e,n){return{id:T("wl","inprocess",e.name,e.toString()),kind:"inprocess",label:n}}function Z(e){return{id:T("run",e.workload.id,"timing",e.configFingerprint,Bun.version,_),workloadId:e.workload.id,phase:"timing",instrumented:!1,configFingerprint:e.configFingerprint,trials:e.trials,timing:e.timing,warnings:e.warnings,artifacts:[],memory:on(e.trials)}}function on(e){let n=e.map((t)=>t.maxRssBytes).filter((t)=>t!==void 0);if(n.length===0)return;return{origin:"resourceUsage",perTrial:e.map((t)=>({rssBytes:t.maxRssBytes})),maxRssBytes:Math.max(...n)}}function Y(e){return{id:T("run",e.workload.id,e.phase,e.configFingerprint,Bun.version,_),workloadId:e.workload.id,phase:e.phase,instrumented:!0,configFingerprint:e.configFingerprint,trials:[{i:0,wallNs:e.diagnosticWallNs,exitCode:e.exitCode}],diagnosticWallNs:e.diagnosticWallNs,cpu:e.cpu,heap:e.heap,jit:e.jit,warnings:e.warnings,artifacts:e.artifacts}}async function ye(e,n,t){let r=await Bun.file(t).arrayBuffer(),o=new Bun.CryptoHasher("sha256");return o.update(r),{id:T("art",e,n,t),kind:n,path:t,sha256:o.digest("hex"),bytes:r.byteLength}}function H(e){return T("cfg",e)}function re(e){return`${JSON.stringify(W(e),null,2)}
4
- `}async function E(e,n){await Bun.write(n,re(e))}async function v(e){let n=await Bun.file(e).text();return JSON.parse(n)}async function se(e){let n=Bun.nanoseconds(),t=Bun.spawn(e.argv,{cwd:e.cwd,env:e.env,stdout:"ignore",stderr:"ignore",stdin:"ignore"}),s=await t.exited,r=Bun.nanoseconds(),o=t.resourceUsage?.();return{wallNs:r-n,exitCode:s,userNs:o?Number(o.cpuTime.user)*1000:void 0,systemNs:o?Number(o.cpuTime.system)*1000:void 0,maxRssBytes:o?.maxRSS}}function xe(e){return e.trim().split(/\s+/).filter(Boolean)}function Re(e){if(e.length===0)throw Error("computeTimingStats: samples must be non-empty");let n=e.length,t=ke(e),s=0;for(let h=0;h<n;h++)s+=e[h];let r=s/n,o=L(t,0.5),i=0;for(let h=0;h<n;h++){let m=e[h]-r;i+=m*m}let a=Math.sqrt(i/n),c=t[0],l=t[n-1],u=L(t,0.25),p=L(t,0.75),d=p-u,b=u-1.5*d,x=p+1.5*d,w=u-3*d,R=p+3*d,k=0,P=0;for(let h=0;h<n;h++){let m=e[h];if(m<w||m>R)P++;else if(m<b||m>x)k++}return{unit:"ns",samples:e,mean:r,median:o,stddev:a,min:c,max:l,outliers:{mild:k,severe:P}}}function ke(e){let n=new Float64Array(e.length);return n.set(e),n.sort(),n}function L(e,n){let t=e.length;if(t===1)return e[0];let s=n*(t-1),r=Math.floor(s),o=Math.ceil(s);if(r===o)return e[r];let i=s-r;return e[r]*(1-i)+e[o]*i}var an=5000000,cn=200;function Pe(e,n,t="subprocess"){let s=[],r=e.samples[0];if(r!==void 0){let i=ke(e.samples),a=L(i,0.25),l=L(i,0.75)-a;if(r>e.median+3*l&&l>0)s.push({code:"slow-first-run",message:`First run took ${(r/1e6).toFixed(2)}ms, much slower than the median ${(e.median/1e6).toFixed(2)}ms. Consider more warmup.`,data:{firstNs:r,medianNs:e.median}})}if(e.outliers.mild+e.outliers.severe>0)s.push({code:"outliers-detected",message:`${e.outliers.mild+e.outliers.severe} outlier(s) detected (${e.outliers.severe} severe, ${e.outliers.mild} mild).`,data:e.outliers});if(t==="subprocess"&&e.median<an)s.push({code:"fast-command",message:`Median run time (${(e.median/1e6).toFixed(3)}ms) is very fast; results may be dominated by spawn overhead.`,data:{medianNs:e.median}});if(t==="inprocess"&&e.median<cn)s.push({code:"below-timer-resolution",message:`Median run time (${e.median.toFixed(0)}ns) is close to timer resolution; consider a larger batch size or a coarser operation.`,data:{medianNs:e.median}});let o=n.filter((i)=>i!==void 0&&i!==0);if(o.length>0)s.push({code:"nonzero-exit",message:`${o.length} of ${n.length} trial(s) exited non-zero.`,data:{exitCodes:o}});return s}var un=10,ln=3000000000,pn=3;async function Q(e){let n=e.warmup??pn;for(let u=0;u<n;u++)await se(e);let t=[],s=e.runs??e.minRuns??un,r=e.runs!==void 0?0:e.minTotalNs??ln,o=0,i=0;while(i<s||o<r){let u=await se(e);if(t.push({i,wallNs:u.wallNs,exitCode:u.exitCode,userNs:u.userNs,systemNs:u.systemNs,maxRssBytes:u.maxRssBytes}),o+=u.wallNs,i++,e.runs!==void 0&&i>=e.runs)break}let a=t.map((u)=>u.wallNs),c=Re(a),l=Pe(c,t.map((u)=>u.exitCode));return{trials:t,timing:c,warnings:l}}var mn=new URL("./runner.ts",import.meta.url).pathname,dn=".ostia";async function oe(e){let t=`${e.outDir??dn}/bench-tmp`,s=e.cwd??process.cwd(),r={timeBudgetMs:e.timeBudgetMs,minSamples:e.minSamples,gc:e.gc},o=[],i=[];try{for(let a of e.suites){let c=a.startsWith("/")?a:`${s}/${a}`,l=`${t}/${T("bench-out",c)}.json`,p=await Bun.spawn(["bun",mn,c,l,JSON.stringify(r)],{cwd:s,stdout:"inherit",stderr:"inherit",stdin:"ignore"}).exited;if(p!==0)throw Error(`Bench suite failed: ${a} (runner exited ${p})`);let d=await v(l);o.push(...d.workloads),i.push(...d.runs)}}finally{await Bun.spawn(["rm","-rf",t]).exited}return M(o,i)}var fn=[],X;function gn(e,n){let t=X;X=e;try{n()}finally{X=t}}function hn(e,n){fn.push({groupName:X,name:e,fn:n})}var J={timingPct:5,frameSelfPct:10,heapTypePct:10,minFrameSelfUs:1000};function ee(e,n){if(e===0)return n===0?0:1/0;return(n-e)/e*100}function O(e,n,t){return e.runs.find((s)=>s.workloadId===n&&s.phase===t)}function ie(e,n,t=J){let s=new Set(n.workloads.map((o)=>o.id)),r=[];for(let o of e.workloads){if(!s.has(o.id))continue;let i=ae(e,n,o.id,t);if(i)r.push(i)}return r}function ae(e,n,t,s=J){let r=O(e,t,"timing"),o=O(n,t,"timing"),i=O(e,t,"cpu"),a=O(n,t,"cpu"),c=O(e,t,"heap"),l=O(n,t,"heap"),u=r?.id??i?.id??c?.id,p=o?.id??a?.id??l?.id;if(!u||!p)return;let d=!1,b;if(r?.timing&&o?.timing){let R=ee(r.timing.median,o.timing.median),k=ee(r.timing.mean,o.timing.mean),P=R>s.timingPct?"regressed":R<-s.timingPct?"improved":"unchanged";if(P==="regressed")d=!0;b={medianDeltaPct:R,meanDeltaPct:k,verdict:P}}let x;if(i?.cpu&&a?.cpu){let R=new Map(i.cpu.totals.map((g)=>[i.cpu.frames[g.frameIx].key,g])),k=new Map(a.cpu.totals.map((g)=>[a.cpu.frames[g.frameIx].key,g])),P=new Map(i.cpu.frames.map((g)=>[g.key,g.name])),h=new Map(a.cpu.frames.map((g)=>[g.key,g.name]));x=[...new Set([...R.keys(),...k.keys()])].map((g)=>{let f=R.get(g)?.selfUs??0,y=k.get(g)?.selfUs??0;return{frameKey:g,name:h.get(g)??P.get(g)??g,baseSelfUs:f,candSelfUs:y,deltaPct:ee(f,y)}}).sort((g,f)=>Math.abs(f.deltaPct)-Math.abs(g.deltaPct));for(let g of x)if((g.baseSelfUs>=s.minFrameSelfUs||g.candSelfUs>=s.minFrameSelfUs)&&g.deltaPct>s.frameSelfPct)d=!0}let w;if(c?.heap&&l?.heap){let R=new Map(c.heap.typeCounts.map((h)=>[h.type,h])),k=new Map(l.heap.typeCounts.map((h)=>[h.type,h]));w=[...new Set([...R.keys(),...k.keys()])].map((h)=>{let m=R.get(h),g=k.get(h);return{type:h,baseCount:m?.count??0,candCount:g?.count??0,baseBytes:m?.retainedBytes,candBytes:g?.retainedBytes,deltaPct:ee(m?.count??0,g?.count??0)}}).sort((h,m)=>Math.abs(m.deltaPct)-Math.abs(h.deltaPct));for(let h of w)if(h.deltaPct>s.heapTypePct)d=!0}return{id:T("cmp",u,p),baselineRunId:u,candidateRunId:p,timing:b,frames:x,heapTypes:w,thresholds:s,verdict:d?"fail":"pass"}}function S(e,n){if(n){let t=e.runs.find((s)=>s.id===n);return t?.cpu?[t]:[]}return e.runs.filter((t)=>t.phase==="cpu"&&t.cpu)}function j(e){let n=e.nodes,t=n.length,s=bn(e),r=new Int32Array(t).fill(-1);for(let c=0;c<t;c++)for(let l of n[c].children){let u=s(l);if(u!==-1)r[u]=c}let o=[];for(let c=0;c<t;c++)if(r[c]===-1)o.push(c);let i=[],a=[];for(let c=o.length-1;c>=0;c--)a.push(o[c]);while(a.length>0){let c=a.pop();i.push(c);for(let l of n[c].children){let u=s(l);if(u!==-1&&r[u]===c)a.push(u)}}return{count:t,indexOf:s,parentIx:r,roots:o,order:i}}function bn(e){let n=e.nodes,t=n.length,s=1/0,r=-1/0,o=!0;for(let a=0;a<t;a++){let c=n[a].id;if(!Number.isInteger(c)){o=!1;break}if(c<s)s=c;if(c>r)r=c}if(o&&t>0&&r-s<t*4+64){let a=r-s+1,c=new Int32Array(a).fill(-1);for(let l=0;l<t;l++)c[n[l].id-s]=l;return(l)=>{let u=l-s;return u>=0&&u<a?c[u]:-1}}let i=new Map;for(let a=0;a<t;a++)i.set(n[a].id,a);return(a)=>i.get(a)??-1}function Ce(e,n){let{count:t,indexOf:s,parentIx:r,order:o}=n,i=new Float64Array(t),a=new Float64Array(t),c=e.samples?.nodeIds??[],l=e.samples?.timeDeltasUs??[];for(let p=0;p<c.length;p++){let d=s(c[p]);if(d===-1)continue;i[d]+=l[p]??0,a[d]+=1}let u=new Float64Array(t);for(let p=o.length-1;p>=0;p--){let d=o[p];u[d]+=i[d];let b=r[d];if(b>=0)u[b]+=u[d]}return{selfUs:i,totalUs:u,samples:a}}var Te={name:"collapsed",async render(e,n={}){return{files:S(e,n.runId).map((r)=>{let o=r.cpu,{nodes:i,frames:a}=o,c=j(o),l=Array(c.count);for(let x of c.order){let w=a[i[x].frameIx].name||"(anonymous)",R=c.parentIx[x];l[x]=R===-1?w:`${l[R]};${w}`}let u=new Float64Array(c.count),p=[],d=o.samples?.nodeIds??[];for(let x=0;x<d.length;x++){let w=c.indexOf(d[x]);if(w===-1)continue;if(u[w]++===0)p.push(w)}let b=Array(p.length);for(let x=0;x<p.length;x++){let w=p[x];b[x]=`${l[w]} ${u[w]}`}return{path:`${r.id}.collapsed.txt`,content:b.join(`
5
- `)+(b.length>0?`
6
- `:"")}})}}};var $e={name:"cpuprofile",async render(e,n={}){let t=S(e,n.runId),s=[],r=[];for(let o of t){if(o.cpu?.origin!=="cpu-prof"&&o.cpu?.origin!=="inspector"){r.push(`${o.id} (origin ${o.cpu?.origin??"unknown"} has no .cpuprofile artifact to pass through)`);continue}let i=o.artifacts.find((c)=>c.kind==="cpuprofile");if(!i){r.push(`${o.id} (no cpuprofile artifact recorded on this run)`);continue}let a=Bun.file(i.path);if(!await a.exists()){r.push(`${o.id} (artifact missing on disk: ${i.path})`);continue}s.push({path:`${o.id}.cpuprofile`,content:await a.text()})}if(s.length===0&&r.length>0)return{text:`No .cpuprofile artifacts available:
7
- ${r.map((o)=>` - ${o}`).join(`
3
+ import{a as z,b as R,c as _,d as v,e as M,f as m,g as K}from"./chunk-j0j2b0fj.js";import{j as y,k as O,l as U,m as H,p as q,s as J,u as b,v as g}from"./chunk-ck12vbed.js";function N(t){return y("cache",t.workloadId,t.phase,t.configFingerprint,t.bunVersion,t.toolVersion,t.instrumented,t.inputsDigest??null)}async function A(t,e=process.cwd()){if(t.length===0)return;let r=new Set;for(let s of t){let a=new Bun.Glob(s);for await(let i of a.scan({cwd:e,absolute:!1}))r.add(i)}let o=[...r].sort(),n=await Promise.all(o.map(async(s)=>{let a=await Bun.file(`${e}/${s}`).arrayBuffer();return{path:s,sha256:Bun.CryptoHasher.hash("sha256",a,"hex")}}));return y("inputs",n)}function E(t,e){return`${t}/cache/${e}.json`}async function I(t,e){let r=Bun.file(E(t,e));if(!await r.exists())return;return await r.json()}async function S(t,e,r){await Bun.write(E(t,e),`${JSON.stringify(r,null,2)}
4
+ `)}var G={runs:null,warmup:3,outDir:".ostia",baseline:"main",cpuIntervalUs:1000,thresholds:R,workloads:[]};async function B(t="ostia.config.json"){let e=Bun.file(t);if(!await e.exists())return;let r=await e.json();return{...G,...r,thresholds:{...R,...r.thresholds??{}}}}function T(t,e){return`${t.outDir}/baselines/${e??t.baseline}.json`}class x extends Error{path;constructor(t){super(`No baseline document at ${t}. Create one with: ostia run --export-json ${t} <command...>`);this.path=t}}async function L(t){let{config:e}=t,r=T(e,t.baselineName);if(!await Bun.file(r).exists())throw new x(r);let n=await g(r),s=[],a=0,i=0,d=0;for(let u of e.workloads){let h=H(u.command,u.label),Z=await A(u.inputs??[]),j=J({runs:e.runs,warmup:e.warmup}),D=N({workloadId:h.id,phase:"timing",configFingerprint:j,bunVersion:Bun.version,toolVersion:O,instrumented:!1,inputsDigest:Z}),F=t.full?void 0:await I(e.outDir,D),k,C;if(F)k=F,C="cached",i++;else{a++;let P=await M({argv:u.command,runs:e.runs??void 0,warmup:e.warmup});k=q({workload:h,configFingerprint:j,trials:P.trials,timing:P.timing,warnings:P.warnings}),await S(e.outDir,D,k),C="executed",d++}s.push({workload:h,status:C,run:k})}let c=U(s.map((u)=>u.workload),s.map((u)=>u.run)),l=0,f=0,p=0;for(let u of s){let h=v(n,c,u.workload.id,e.thresholds);if(!h){p++;continue}if(u.comparison=h,h.verdict==="pass")l++;else f++}return c.comparisons=s.map((u)=>u.comparison).filter((u)=>u!==void 0),{document:c,summary:{total:e.workloads.length,affected:a,cached:i,executed:d,passed:l,regressed:f,missingBaseline:p,results:s}}}function V(t){let e=[];if(e.push(`${t.total} workloads`),e.push(`${t.affected} affected by this change`),e.push(`${t.cached} cached`),e.push(`${t.executed} executed`),t.missingBaseline>0)e.push(`${t.missingBaseline} skipped (no matching baseline workload)`);let r=t.results.filter((o)=>o.comparison?.verdict==="fail").map((o)=>{let n=o.comparison.timing,s=o.workload.label??o.workload.command?.join(" ")??o.workload.id;return n?`${n.medianDeltaPct>0?"+":""}${n.medianDeltaPct.toFixed(1)}% median on ${s}`:s});return e.push(`${t.passed} passed ${t.regressed} regressed${r.length>0?` (${r.join(", ")})`:""}`),e.push(""),e.push(`Profile CI: ${t.regressed>0?"\u2717":"\u2713"}`),`${e.join(`
8
5
  `)}
9
- `};return{files:s}}};var Ne={name:"json",async render(e){return{text:re(e)}}};var Ie={name:"jsonl",async render(e){let{runs:n,...t}=e;return{text:`${[q(t),...n.map((r)=>q(r))].join(`
10
- `)}
11
- `}}};function B(e){return(e/1e6).toFixed(3)}function ne(e){return e?.label??e?.command?.join(" ")??e?.entry?.task??e?.id??"unknown"}var Fe=10,De=10,ve={name:"markdown",async render(e){let n=new Map(e.workloads.map((r)=>[r.id,r])),t=[];t.push("# Profile Report",""),t.push(`Bun ${e.bunVersion} \xB7 ostia ${e.toolVersion} \xB7 ${e.platform.os}/${e.platform.arch} \xB7 ${e.createdAt}`,"");let s=e.runs.filter((r)=>r.phase==="timing"&&r.timing!==void 0);if(s.length>0){t.push("## Timing",""),t.push("| Command | Mean \xB1 SD (ms) | Min\u2026Max (ms) | Median (ms) |","|---|---|---|---|");for(let o of s){let i=ne(n.get(o.workloadId)),a=o.timing;t.push(`| ${i} | ${B(a.mean)} \xB1 ${B(a.stddev)} | ${B(a.min)}\u2026${B(a.max)} | ${B(a.median)} |`)}t.push("");let r=s.filter((o)=>o.warnings.length>0);if(r.length>0){t.push("### Warnings","");for(let o of r){let i=ne(n.get(o.workloadId));for(let a of o.warnings)t.push(`- **${i}**: ${a.message} (\`${a.code}\`)`)}t.push("")}}for(let r of e.runs){if(r.phase!=="cpu"&&r.phase!=="heap")continue;let o=ne(n.get(r.workloadId));if(r.phase==="cpu"){if(t.push(`## CPU capture - ${o}`,""),t.push(`instrumented, diagnostic wall ${B(r.diagnosticWallNs??0)}ms`,""),r.cpu){t.push(`origin: \`${r.cpu.origin}\`, interval: ${r.cpu.samplingIntervalUs}\xB5s`,""),t.push("| Self % | Self (ms) | Total (ms) | Frame |","|---|---|---|---|");let i=r.cpu.totals.reduce((a,c)=>a+c.selfUs,0)||1;for(let a of r.cpu.totals.slice(0,Fe)){let c=r.cpu.frames[a.frameIx],l=(a.selfUs/i*100).toFixed(1);t.push(`| ${l}% | ${(a.selfUs/1000).toFixed(2)} | ${(a.totalUs/1000).toFixed(2)} | ${c?.name||"(anonymous)"} |`)}if(t.push(""),r.jit){let a=r.jit.tiers;t.push(`JIT tiers: LLInt ${a.llint} \xB7 Baseline ${a.baseline} \xB7 DFG ${a.dfg} \xB7 FTL ${a.ftl}`,"")}}}else if(t.push(`## Heap snapshot - ${o}`,""),t.push(`instrumented, diagnostic wall ${B(r.diagnosticWallNs??0)}ms`,""),r.heap){t.push(`${r.heap.objectCount??"?"} objects, ${((r.heap.heapSizeBytes??0)/1e6).toFixed(2)}MB`,""),t.push("| Count | Type |","|---|---|");for(let i of r.heap.typeCounts.slice(0,De))t.push(`| ${i.count} | ${i.type} |`);t.push("")}for(let i of r.artifacts)t.push(`- artifact: \`${i.path}\``);for(let i of r.warnings)t.push(`- ! ${i.message} (\`${i.code}\`)`);if(r.artifacts.length>0||r.warnings.length>0)t.push("")}if(e.comparisons&&e.comparisons.length>0){t.push("## Comparisons","");for(let r of e.comparisons){let o=e.runs.find((a)=>a.id===r.candidateRunId),i=ne(o?n.get(o.workloadId):void 0);if(t.push(`### ${r.verdict==="pass"?"\u2713":"\u2717"} ${i}`,""),r.timing){let a=r.timing.medianDeltaPct>0?"+":"";t.push(`- timing: ${a}${r.timing.medianDeltaPct.toFixed(1)}% median (**${r.timing.verdict}**)`)}for(let a of r.frames?.slice(0,Fe)??[]){if(Math.abs(a.deltaPct)<0.5)continue;let c=a.deltaPct>0?"+":"";t.push(`- frame \`${a.name}\`: ${c}${a.deltaPct.toFixed(1)}% self-time (${(a.baseSelfUs/1000).toFixed(2)}ms \u2192 ${(a.candSelfUs/1000).toFixed(2)}ms)`)}for(let a of r.heapTypes?.slice(0,De)??[]){if(Math.abs(a.deltaPct)<0.5)continue;let c=a.deltaPct>0?"+":"";t.push(`- heap \`${a.type}\`: ${c}${a.deltaPct.toFixed(1)}% count (${a.baseCount} \u2192 ${a.candCount})`)}t.push("")}}return{text:t.join(`
12
- `)}}};var wn=15;function ce(e){return`n${e}`}function yn(e,n,t){return`${(e||"(anonymous)").replace(/"/g,"'")} (self ${(n/1000).toFixed(2)}ms, total ${(t/1000).toFixed(2)}ms)`}function xn(e,n,t,s){let r=[];if(s<=0)return r;for(let o=0;o<n;o++){if(o===t)continue;let i=e[o];if(r.length===s&&i<=e[r[s-1]])continue;let a=r.length;while(a>0&&e[r[a-1]]<i)a--;if(r.splice(a,0,o),r.length>s)r.pop()}return r}var Ue={name:"mermaid",async render(e,n={}){let t=n.topN??wn;return{files:S(e,n.runId).map((o)=>{let i=o.cpu,{nodes:a,frames:c}=i,l=j(i),{selfUs:u,totalUs:p}=Ce(i,l),{parentIx:d}=l,b=l.roots[0]??-1,x=xn(u,l.count,b,t),w=new Set(b!==-1?[b]:[]),R=[];for(let P of x){R.length=0;for(let h=P;h!==-1;h=d[h])R.push(h);for(let h=R.length-1;h>=0;h--)w.add(R[h])}let k=["graph TD"];for(let P of w){let h=a[P].id;k.push(` ${ce(h)}["${yn(c[a[P].frameIx].name,u[P],p[P])}"]`)}for(let P of w){let h=d[P];if(h!==-1&&w.has(h))k.push(` ${ce(a[h].id)} --> ${ce(a[P].id)}`)}return{path:`${o.id}.mermaid.md`,content:`${k.join(`
13
- `)}
14
- `}})}}};var Rn="https://www.speedscope.app/file-format-schema.json";function Se(e){return e?.label??e?.command?.join(" ")??e?.entry?.task??"profile"}var Be={name:"speedscope",async render(e,n={}){let t=S(e,n.runId),s=new Map(e.workloads.map((o)=>[o.id,o]));return{files:t.map((o)=>{let i=o.cpu,{nodes:a}=i,c=j(i),l=i.samples?.nodeIds??[],u=i.samples?.timeDeltasUs??[],p=Array(c.count);for(let w of c.order){let R=c.parentIx[w],k=a[w].frameIx;p[w]=R===-1?[k]:[...p[R],k]}let d=Array(l.length);for(let w=0;w<l.length;w++){let R=c.indexOf(l[w]);d[w]=R===-1?[]:p[R]}let b=0;for(let w=0;w<u.length;w++)b+=u[w];let x={$schema:Rn,exporter:"ostia",name:Se(s.get(o.workloadId)),activeProfileIndex:0,shared:{frames:i.frames.map((w)=>({name:w.name||"(anonymous)",file:w.url,line:w.line!==void 0?w.line+1:void 0}))},profiles:[{type:"sampled",name:Se(s.get(o.workloadId)),unit:"microseconds",startValue:0,endValue:b,samples:d,weights:u}]};return{path:`${o.id}.speedscope.json`,content:`${JSON.stringify(x,null,2)}
15
- `}})}}};function z(e){return(e/1e6).toFixed(3)}function ue(e){return e.label??e.command?.join(" ")??e.entry?.task??e.id}var Me={name:"table",async render(e){let n=e.runs.filter((p)=>p.phase==="timing"&&p.timing!==void 0),t=new Map(e.workloads.map((p)=>[p.id,p]));if(n.length===0){let p=Ae(e,t);return{text:p.length>0?`${p.join(`
16
- `)}
17
- `:`(no timing runs)
18
- `}}let s=n.map((p)=>{let d=t.get(p.workloadId);return{run:p,workload:d,label:d?ue(d):p.workloadId}}),r=Math.min(...s.map((p)=>p.run.timing.median)),o=s.length>1,i=[],a=Math.max(7,...s.map((p)=>p.label.length)),c=o?`${"Command".padEnd(a)} Mean [ms] Min\u2026Max [ms] Relative`:`${"Command".padEnd(a)} Mean [ms] Min\u2026Max [ms]`;i.push(c),i.push("-".repeat(c.length));for(let{run:p,label:d}of s){let b=p.timing,x=`${z(b.mean)} \xB1 ${z(b.stddev)}`,w=`${z(b.min)}\u2026${z(b.max)}`,R=`${d.padEnd(a)} ${x.padEnd(15)} ${w.padEnd(18)}`;if(o){let k=b.median/r;R+=k===1?" 1.00\xD7":` ${k.toFixed(2)}\xD7 slower`}i.push(R);for(let k of p.warnings)i.push(` ! ${k.message}`)}let l=Pn(e,t);if(l.length>0)i.push(""),i.push(...l);let u=Ae(e,t);if(u.length>0)i.push(""),i.push(...u);return{text:`${i.join(`
19
- `)}
20
- `}}};function kn(e,n,t){let s=e.runs.find((o)=>o.id===t),r=s?n.get(s.workloadId):void 0;return r?ue(r):t}function Ae(e,n){if(!e.comparisons||e.comparisons.length===0)return[];let t=[];for(let s of e.comparisons){let r=kn(e,n,s.candidateRunId),o=s.verdict==="pass"?"\u2713":"\u2717";if(t.push(`${o} ${r}`),s.timing){let i=s.timing.medianDeltaPct>0?"+":"";t.push(` timing: ${i}${s.timing.medianDeltaPct.toFixed(1)}% median (${s.timing.verdict})`)}if(s.frames)for(let i of s.frames.slice(0,Ee)){if(Math.abs(i.deltaPct)<0.5)continue;let a=i.deltaPct>0?"+":"";t.push(` frame ${i.name}: ${a}${i.deltaPct.toFixed(1)}% self-time (${(i.baseSelfUs/1000).toFixed(2)}ms -> ${(i.candSelfUs/1000).toFixed(2)}ms)`)}if(s.heapTypes)for(let i of s.heapTypes.slice(0,Oe)){if(Math.abs(i.deltaPct)<0.5)continue;let a=i.deltaPct>0?"+":"";t.push(` heap ${i.type}: ${a}${i.deltaPct.toFixed(1)}% count (${i.baseCount} -> ${i.candCount})`)}}return t}var Ee=5,Oe=5;function Pn(e,n){let t=[];for(let s of e.runs){if(s.phase!=="cpu"&&s.phase!=="heap")continue;let r=n.get(s.workloadId),o=r?ue(r):s.workloadId;if(s.phase==="cpu")if(s.cpu){t.push(`CPU capture - ${o} (instrumented, ${s.cpu.samplingIntervalUs}\xB5s interval, diagnostic wall ${z(s.diagnosticWallNs??0)}ms)`);let i=s.cpu.totals.reduce((a,c)=>a+c.selfUs,0)||1;for(let a of s.cpu.totals.slice(0,Ee)){let c=s.cpu.frames[a.frameIx],l=(a.selfUs/i*100).toFixed(1);t.push(` ${l.padStart(5)}% ${(a.selfUs/1000).toFixed(2).padStart(8)}ms self ${c?.name??"?"}`)}}else t.push(`CPU capture - ${o} (instrumented, no evidence captured)`);else if(s.heap){let i=((s.heap.heapSizeBytes??0)/1e6).toFixed(2);t.push(`Heap snapshot - ${o} (instrumented, ${s.heap.objectCount??"?"} objects, ${i}MB)`);for(let a of s.heap.typeCounts.slice(0,Oe))t.push(` ${String(a.count).padStart(6)} ${a.type}`)}else t.push(`Heap snapshot - ${o} (instrumented, no evidence captured)`);for(let i of s.artifacts)t.push(` artifact: ${i.path}`);for(let i of s.warnings)t.push(` ! ${i.message}`)}return t}var I={table:Me,json:Ne,markdown:ve,jsonl:Ie,collapsed:Te,mermaid:Ue,speedscope:Be,cpuprofile:$e};var Cn=".ostia",le=1000;async function We(e){let n=H({runs:e.runs??null,warmup:e.warmup??null,cpu:e.cpu??!1,heap:e.heap??!1,cpuIntervalUs:e.cpuIntervalUs??le}),s=`${e.outDir??Cn}/artifacts`,r=[],o=[];for(let i of e.commands){let a=Array.isArray(i)?i:xe(i),c=G(a,Array.isArray(i)?void 0:i);r.push(c);let l=await Q({argv:a,cwd:e.cwd,env:e.env,runs:e.runs,warmup:e.warmup}),u=Z({workload:c,configFingerprint:n,trials:l.trials,timing:l.timing,warnings:l.warnings});if(o.push(u),e.cpu){let p=`${u.id}-cpu.cpuprofile`,d=await pe({argv:a,cwd:e.cwd,env:e.env,artifactDir:s,fileName:p,intervalUs:e.cpuIntervalUs??le});o.push(await je({workload:c,phase:"cpu",configFingerprint:n,diagnosticWallNs:d.diagnosticWallNs,exitCode:d.exitCode,cpu:d.cpu,artifactPath:d.artifactPath,artifactKind:"cpuprofile",warnings:d.warnings}))}if(e.heap){let p=`${u.id}-heap.heapsnapshot`,d=await de({argv:a,cwd:e.cwd,env:e.env,artifactDir:s,fileName:p});o.push(await je({workload:c,phase:"heap",configFingerprint:n,diagnosticWallNs:d.diagnosticWallNs,exitCode:d.exitCode,heap:d.heap,artifactPath:d.artifactPath,artifactKind:"heapsnapshot",warnings:d.warnings}))}}return M(r,o)}async function je(e){let n=`${e.workload.id}-${e.phase}-${e.configFingerprint}`,t=e.artifactPath?[await ye(n,e.artifactKind,e.artifactPath)]:[];return Y({workload:e.workload,phase:e.phase,configFingerprint:e.configFingerprint,diagnosticWallNs:e.diagnosticWallNs,exitCode:e.exitCode,cpu:e.cpu,heap:e.heap,warnings:e.warnings,artifacts:t})}async function Yt(e,n={}){let t=we(e),s=H({intervalUs:n.intervalUs??le,origin:n.origin??"inspector"}),r=(l)=>l.samples?.nodeIds.length===0?[{code:"empty-profile",message:"In-process capture produced zero samples."}]:[];if(n.origin==="jsc"){let{result:l,cpu:u,jit:p,diagnosticWallNs:d}=await be(e,n),b=Y({workload:t,phase:"cpu",configFingerprint:s,diagnosticWallNs:d,cpu:u,jit:p,warnings:r(u),artifacts:[]});return{result:l,run:b}}let{result:o,cpu:i,diagnosticWallNs:a}=await fe(e,n),c=Y({workload:t,phase:"cpu",configFingerprint:s,diagnosticWallNs:a,cpu:i,warnings:r(i),artifacts:[]});return{result:o,run:c}}function _e(e){return T("cache",e.workloadId,e.phase,e.configFingerprint,e.bunVersion,e.toolVersion,e.instrumented,e.inputsDigest??null)}async function He(e,n=process.cwd()){if(e.length===0)return;let t=new Set;for(let o of e){let i=new Bun.Glob(o);for await(let a of i.scan({cwd:n,absolute:!1}))t.add(a)}let s=[...t].sort(),r=await Promise.all(s.map(async(o)=>{let i=await Bun.file(`${n}/${o}`).arrayBuffer();return{path:o,sha256:Bun.CryptoHasher.hash("sha256",i,"hex")}}));return T("inputs",r)}function Le(e,n){return`${e}/cache/${n}.json`}async function Je(e,n){let t=Bun.file(Le(e,n));if(!await t.exists())return;return await t.json()}async function ze(e,n,t){await Bun.write(Le(e,n),`${JSON.stringify(t,null,2)}
21
- `)}var Tn={runs:null,warmup:3,outDir:".ostia",baseline:"main",cpuIntervalUs:1000,thresholds:J,workloads:[]};async function Ve(e="ostia.config.json"){let n=Bun.file(e);if(!await n.exists())return;let t=await n.json();return{...Tn,...t,thresholds:{...J,...t.thresholds??{}}}}function qe(e,n){return`${e.outDir}/baselines/${n??e.baseline}.json`}class te extends Error{path;constructor(e){super(`No baseline document at ${e}. Create one with: ostia run --export-json ${e} <command...>`);this.path=e}}async function Ke(e){let{config:n}=e,t=qe(n,e.baselineName);if(!await Bun.file(t).exists())throw new te(t);let r=await v(t),o=[],i=0,a=0,c=0;for(let b of n.workloads){let x=G(b.command,b.label),w=await He(b.inputs??[]),R=H({runs:n.runs,warmup:n.warmup}),k=_e({workloadId:x.id,phase:"timing",configFingerprint:R,bunVersion:Bun.version,toolVersion:_,instrumented:!1,inputsDigest:w}),P=e.full?void 0:await Je(n.outDir,k),h,m;if(P)h=P,m="cached",a++;else{i++;let g=await Q({argv:b.command,runs:n.runs??void 0,warmup:n.warmup});h=Z({workload:x,configFingerprint:R,trials:g.trials,timing:g.timing,warnings:g.warnings}),await ze(n.outDir,k,h),m="executed",c++}o.push({workload:x,status:m,run:h})}let l=M(o.map((b)=>b.workload),o.map((b)=>b.run)),u=0,p=0,d=0;for(let b of o){let x=ae(r,l,b.workload.id,n.thresholds);if(!x){d++;continue}if(b.comparison=x,x.verdict==="pass")u++;else p++}return l.comparisons=o.map((b)=>b.comparison).filter((b)=>b!==void 0),{document:l,summary:{total:n.workloads.length,affected:i,cached:a,executed:c,passed:u,regressed:p,missingBaseline:d,results:o}}}function Ge(e){let n=[];if(n.push(`${e.total} workloads`),n.push(`${e.affected} affected by this change`),n.push(`${e.cached} cached`),n.push(`${e.executed} executed`),e.missingBaseline>0)n.push(`${e.missingBaseline} skipped (no matching baseline workload)`);let t=e.results.filter((s)=>s.comparison?.verdict==="fail").map((s)=>{let r=s.comparison.timing,o=s.workload.label??s.workload.command?.join(" ")??s.workload.id;return r?`${r.medianDeltaPct>0?"+":""}${r.medianDeltaPct.toFixed(1)}% median on ${o}`:o});return n.push(`${e.passed} passed ${e.regressed} regressed${t.length>0?` (${t.join(", ")})`:""}`),n.push(""),n.push(`Profile CI: ${e.regressed>0?"\u2717":"\u2713"}`),`${n.join(`
22
- `)}
23
- `}async function V(e,n){if(e.text)process.stdout.write(e.text);if(!e.files||e.files.length===0)return;if(n)for(let t of e.files){let s=t.path?`${n}/${t.path}`:n;await Bun.write(s,t.content),process.stdout.write(`wrote ${s}
24
- `)}else if(e.files.length===1)process.stdout.write(e.files[0].content);else for(let t of e.files)process.stdout.write(`--- ${t.path??"(unnamed)"} ---
25
- ${t.content}
26
- `)}var $n=`ostia run [flags] <command...>
6
+ `}async function w(t,e){if(t.text)process.stdout.write(t.text);if(!t.files||t.files.length===0)return;if(e)for(let r of t.files){let o=r.path?`${e}/${r.path}`:e;await Bun.write(o,r.content),process.stdout.write(`wrote ${o}
7
+ `)}else if(t.files.length===1)process.stdout.write(t.files[0].content);else for(let r of t.files)process.stdout.write(`--- ${r.path??"(unnamed)"} ---
8
+ ${r.content}
9
+ `)}var Q=`ostia run [flags] <command...>
27
10
 
28
11
  Run one or more commands N times with warmup and report timing statistics.
29
12
 
@@ -47,7 +30,7 @@ Examples:
47
30
  ostia run --runs 25 --warmup 3 "bun a.ts" "bun b.ts"
48
31
  ostia run --cpu --heap "bun src/server.ts"
49
32
  ostia run --format json "bun a.ts"
50
- `,Nn=`ostia bench [flags] <suite.ts...>
33
+ `,X=`ostia bench [flags] <suite.ts...>
51
34
 
52
35
  Run in-process benchmark suites (registered via group()/task()). Each suite file runs
53
36
  in its own spawned child process (isolated from CLI startup state).
@@ -71,7 +54,7 @@ Suite files register tasks like:
71
54
  Examples:
72
55
  ostia bench benches/parse.ts
73
56
  ostia bench --time-budget 1000 --min-samples 50 benches/*.ts
74
- `,Ze=`ostia compare <base.json> <candidate.json>
57
+ `,W=`ostia compare <base.json> <candidate.json>
75
58
  ostia compare <candidate.json> --baseline <path.json>
76
59
 
77
60
  Compare two ProfileDocuments (matched by workload id) and rank timing/frame/heap deltas.
@@ -85,10 +68,10 @@ Flags:
85
68
  Examples:
86
69
  ostia compare before.json after.json
87
70
  ostia compare after.json --baseline .ostia/baselines/main.json
88
- `,In=`ostia report <document.json> [--format table|json|markdown|jsonl]
71
+ `,Y=`ostia report <document.json> [--format table|json|markdown|jsonl]
89
72
 
90
73
  Render a saved ProfileDocument.
91
- `,Fn=`ostia viz <document.json> --format FORMAT [--run <id>] [--out-dir PATH]
74
+ `,ee=`ostia viz <document.json> --format FORMAT [--run <id>] [--out-dir PATH]
92
75
 
93
76
  Render CPU evidence from a saved ProfileDocument as a visualization artifact. Files,
94
77
  not a GUI - hand the output to speedscope.app, flamegraph.pl, or
@@ -109,7 +92,7 @@ Flags:
109
92
  Examples:
110
93
  ostia viz run.json --format speedscope --out-dir .ostia/viz
111
94
  ostia viz run.json --format collapsed | flamegraph.pl > flame.svg
112
- `,Dn=`ostia ci [--full] [--baseline NAME]
95
+ `,te=`ostia ci [--full] [--baseline NAME]
113
96
 
114
97
  Load ostia.config.json, run configured workloads (reusing cached results when their
115
98
  fingerprint is unchanged), compare against the named baseline, and gate on regressions.
@@ -122,21 +105,21 @@ Flags:
122
105
  --help show this message
123
106
 
124
107
  Exit codes: 0 pass, 1 regression, 2 harness error (missing config/baseline, spawn failure).
125
- `;function vn(e){let n=[],t,s,r=!1,o=!1,i,a,c,l="table",u=!1,p=!1;for(let d=0;d<e.length;d++){let b=e[d];switch(b){case"--runs":t=Number(e[++d]);break;case"--warmup":s=Number(e[++d]);break;case"--cpu":r=!0;break;case"--heap":o=!0;break;case"--cpu-interval":i=Number(e[++d]);break;case"--out-dir":a=e[++d];break;case"--export-json":c=e[++d];break;case"--format":l=e[++d];break;case"--quiet":u=!0;break;case"--help":case"-h":p=!0;break;default:n.push(b)}}return{commands:n,runs:t,warmup:s,cpu:r,heap:o,cpuIntervalUs:i,outDir:a,exportJson:c,format:l,quiet:u,help:p}}async function Un(e){let n=vn(e);if(n.help||n.commands.length===0)return process.stdout.write($n),n.help?0:2;if(!(n.format in I))return process.stderr.write(`Unknown --format "${n.format}". Expected one of: ${Object.keys(I).join(", ")}
126
- `),2;let t;try{t=await We({commands:n.commands,runs:n.runs,warmup:n.warmup,cpu:n.cpu,heap:n.heap,cpuIntervalUs:n.cpuIntervalUs,outDir:n.outDir})}catch(r){return process.stderr.write(`Run failed: ${r instanceof Error?r.message:String(r)}
127
- `),2}if(n.exportJson)await E(t,n.exportJson);if(!n.quiet){let o=await I[n.format].render(t,{});await V(o)}return t.runs.some((r)=>r.trials.some((o)=>o.exitCode!==void 0&&o.exitCode!==0))?1:0}function Sn(e){let n=[],t,s,r=!1,o,i,a="table",c=!1,l=!1;for(let u=0;u<e.length;u++){let p=e[u];switch(p){case"--time-budget":t=Number(e[++u]);break;case"--min-samples":s=Number(e[++u]);break;case"--gc":r=!0;break;case"--out-dir":o=e[++u];break;case"--export-json":i=e[++u];break;case"--format":a=e[++u];break;case"--quiet":c=!0;break;case"--help":case"-h":l=!0;break;default:n.push(p)}}return{suites:n,timeBudgetMs:t,minSamples:s,gc:r,outDir:o,exportJson:i,format:a,quiet:c,help:l}}async function Bn(e){let n=Sn(e);if(n.help||n.suites.length===0)return process.stdout.write(Nn),n.help?0:2;if(!(n.format in I))return process.stderr.write(`Unknown --format "${n.format}". Expected one of: ${Object.keys(I).join(", ")}
128
- `),2;let t;try{t=await oe({suites:n.suites,timeBudgetMs:n.timeBudgetMs,minSamples:n.minSamples,gc:n.gc,outDir:n.outDir})}catch(s){return process.stderr.write(`Bench failed: ${s instanceof Error?s.message:String(s)}
129
- `),2}if(n.exportJson)await E(t,n.exportJson);if(!n.quiet){let r=await I[n.format].render(t,{});await V(r)}return 0}function An(e){let n=[],t,s,r="table",o=!1,i=!1;for(let a=0;a<e.length;a++){let c=e[a];switch(c){case"--baseline":t=e[++a];break;case"--export-json":s=e[++a];break;case"--format":r=e[++a];break;case"--quiet":o=!0;break;case"--help":case"-h":i=!0;break;default:n.push(c)}}return{paths:n,baseline:t,exportJson:s,format:r,quiet:o,help:i}}async function Mn(e){let n=An(e);if(n.help)return process.stdout.write(Ze),0;let t,s;if(n.baseline)t=n.baseline,s=n.paths[0];else t=n.paths[0],s=n.paths[1];if(!t||!s)return process.stdout.write(Ze),2;let r,o;try{[r,o]=await Promise.all([v(t),v(s)])}catch(l){return process.stderr.write(`Failed to load documents: ${l instanceof Error?l.message:String(l)}
130
- `),2}let i=ie(r,o),a={...o,comparisons:i};if(n.exportJson)await E(a,n.exportJson);if(!n.quiet){let u=await I[n.format].render(a,{});await V(u)}return i.some((l)=>l.verdict==="fail")?1:0}function En(e){let n,t="table",s=!1;for(let r=0;r<e.length;r++){let o=e[r];switch(o){case"--format":t=e[++r];break;case"--help":case"-h":s=!0;break;default:n=o}}return{path:n,format:t,help:s}}async function On(e){let n=En(e);if(n.help||!n.path)return process.stdout.write(In),n.help?0:2;let t;try{t=await v(n.path)}catch(o){return process.stderr.write(`Failed to load ${n.path}: ${o instanceof Error?o.message:String(o)}
131
- `),2}let r=await I[n.format].render(t,{});return await V(r),0}var jn={ascii:"table"};function Wn(e){let n,t,s,r,o=!1;for(let i=0;i<e.length;i++){let a=e[i];switch(a){case"--format":{let c=e[++i]??"";t=jn[c]??c;break}case"--run":s=e[++i];break;case"--out-dir":r=e[++i];break;case"--help":case"-h":o=!0;break;default:n=a}}return{path:n,format:t,runId:s,outDir:r,help:o}}async function _n(e){let n=Wn(e);if(n.help||!n.path||!n.format)return process.stdout.write(Fn),n.help?0:2;if(!(n.format in I))return process.stderr.write(`Unknown --format "${n.format}". Expected one of: ${Object.keys(I).join(", ")}, ascii
132
- `),2;let t;try{t=await v(n.path)}catch(o){return process.stderr.write(`Failed to load ${n.path}: ${o instanceof Error?o.message:String(o)}
133
- `),2}let r=await I[n.format].render(t,{runId:n.runId});if(!r.text&&(!r.files||r.files.length===0))return process.stderr.write(n.runId?`No CPU evidence found for run "${n.runId}".
108
+ `;function re(t){let e=[],r,o,n=!1,s=!1,a,i,d,c="table",l=!1,f=!1;for(let p=0;p<t.length;p++){let u=t[p];switch(u){case"--runs":r=Number(t[++p]);break;case"--warmup":o=Number(t[++p]);break;case"--cpu":n=!0;break;case"--heap":s=!0;break;case"--cpu-interval":a=Number(t[++p]);break;case"--out-dir":i=t[++p];break;case"--export-json":d=t[++p];break;case"--format":c=t[++p];break;case"--quiet":l=!0;break;case"--help":case"-h":f=!0;break;default:e.push(u)}}return{commands:e,runs:r,warmup:o,cpu:n,heap:s,cpuIntervalUs:a,outDir:i,exportJson:d,format:c,quiet:l,help:f}}async function ne(t){let e=re(t);if(e.help||e.commands.length===0)return process.stdout.write(Q),e.help?0:2;if(!(e.format in m))return process.stderr.write(`Unknown --format "${e.format}". Expected one of: ${Object.keys(m).join(", ")}
109
+ `),2;let r;try{r=await K({commands:e.commands,runs:e.runs,warmup:e.warmup,cpu:e.cpu,heap:e.heap,cpuIntervalUs:e.cpuIntervalUs,outDir:e.outDir})}catch(n){return process.stderr.write(`Run failed: ${n instanceof Error?n.message:String(n)}
110
+ `),2}if(e.exportJson)await b(r,e.exportJson);if(!e.quiet){let s=await m[e.format].render(r,{});await w(s)}return r.runs.some((n)=>n.trials.some((s)=>s.exitCode!==void 0&&s.exitCode!==0))?1:0}function se(t){let e=[],r,o,n=!1,s,a,i="table",d=!1,c=!1;for(let l=0;l<t.length;l++){let f=t[l];switch(f){case"--time-budget":r=Number(t[++l]);break;case"--min-samples":o=Number(t[++l]);break;case"--gc":n=!0;break;case"--out-dir":s=t[++l];break;case"--export-json":a=t[++l];break;case"--format":i=t[++l];break;case"--quiet":d=!0;break;case"--help":case"-h":c=!0;break;default:e.push(f)}}return{suites:e,timeBudgetMs:r,minSamples:o,gc:n,outDir:s,exportJson:a,format:i,quiet:d,help:c}}async function oe(t){let e=se(t);if(e.help||e.suites.length===0)return process.stdout.write(X),e.help?0:2;if(!(e.format in m))return process.stderr.write(`Unknown --format "${e.format}". Expected one of: ${Object.keys(m).join(", ")}
111
+ `),2;let r;try{r=await z({suites:e.suites,timeBudgetMs:e.timeBudgetMs,minSamples:e.minSamples,gc:e.gc,outDir:e.outDir})}catch(o){return process.stderr.write(`Bench failed: ${o instanceof Error?o.message:String(o)}
112
+ `),2}if(e.exportJson)await b(r,e.exportJson);if(!e.quiet){let n=await m[e.format].render(r,{});await w(n)}return 0}function ae(t){let e=[],r,o,n="table",s=!1,a=!1;for(let i=0;i<t.length;i++){let d=t[i];switch(d){case"--baseline":r=t[++i];break;case"--export-json":o=t[++i];break;case"--format":n=t[++i];break;case"--quiet":s=!0;break;case"--help":case"-h":a=!0;break;default:e.push(d)}}return{paths:e,baseline:r,exportJson:o,format:n,quiet:s,help:a}}async function ie(t){let e=ae(t);if(e.help)return process.stdout.write(W),0;let r,o;if(e.baseline)r=e.baseline,o=e.paths[0];else r=e.paths[0],o=e.paths[1];if(!r||!o)return process.stdout.write(W),2;let n,s;try{[n,s]=await Promise.all([g(r),g(o)])}catch(c){return process.stderr.write(`Failed to load documents: ${c instanceof Error?c.message:String(c)}
113
+ `),2}let a=_(n,s),i={...s,comparisons:a};if(e.exportJson)await b(i,e.exportJson);if(!e.quiet){let l=await m[e.format].render(i,{});await w(l)}return a.some((c)=>c.verdict==="fail")?1:0}function ue(t){let e,r="table",o=!1;for(let n=0;n<t.length;n++){let s=t[n];switch(s){case"--format":r=t[++n];break;case"--help":case"-h":o=!0;break;default:e=s}}return{path:e,format:r,help:o}}async function ce(t){let e=ue(t);if(e.help||!e.path)return process.stdout.write(Y),e.help?0:2;let r;try{r=await g(e.path)}catch(s){return process.stderr.write(`Failed to load ${e.path}: ${s instanceof Error?s.message:String(s)}
114
+ `),2}let n=await m[e.format].render(r,{});return await w(n),0}var le={ascii:"table"};function de(t){let e,r,o,n,s=!1;for(let a=0;a<t.length;a++){let i=t[a];switch(i){case"--format":{let d=t[++a]??"";r=le[d]??d;break}case"--run":o=t[++a];break;case"--out-dir":n=t[++a];break;case"--help":case"-h":s=!0;break;default:e=i}}return{path:e,format:r,runId:o,outDir:n,help:s}}async function pe(t){let e=de(t);if(e.help||!e.path||!e.format)return process.stdout.write(ee),e.help?0:2;if(!(e.format in m))return process.stderr.write(`Unknown --format "${e.format}". Expected one of: ${Object.keys(m).join(", ")}, ascii
115
+ `),2;let r;try{r=await g(e.path)}catch(s){return process.stderr.write(`Failed to load ${e.path}: ${s instanceof Error?s.message:String(s)}
116
+ `),2}let n=await m[e.format].render(r,{runId:e.runId});if(!n.text&&(!n.files||n.files.length===0))return process.stderr.write(e.runId?`No CPU evidence found for run "${e.runId}".
134
117
  `:`No CPU evidence found in this document (no cpu-phase runs). Capture some with "ostia run --cpu ...".
135
- `),2;return await V(r,n.outDir),0}function Hn(e){let n=!1,t,s,r=!1,o=!1;for(let i=0;i<e.length;i++)switch(e[i]){case"--full":n=!0;break;case"--baseline":t=e[++i];break;case"--export-json":s=e[++i];break;case"--quiet":r=!0;break;case"--help":case"-h":o=!0;break}return{full:n,baseline:t,exportJson:s,quiet:r,help:o}}async function Ln(e){let n=Hn(e);if(n.help)return process.stdout.write(Dn),0;let t=await Ve();if(!t)return process.stderr.write(`No ostia.config.json found. "ostia ci" needs configured workloads.
136
- `),2;if(t.workloads.length===0)return process.stderr.write(`ostia.config.json has no "workloads" configured.
137
- `),2;let s;try{s=await Ke({config:t,full:n.full,baselineName:n.baseline})}catch(r){if(r instanceof te)return process.stderr.write(`${r.message}
138
- `),2;return process.stderr.write(`CI run failed: ${r instanceof Error?r.message:String(r)}
139
- `),2}if(n.exportJson)await E(s.document,n.exportJson);if(!n.quiet)process.stdout.write(Ge(s.summary));return s.summary.regressed>0?1:0}async function Jn(){let[e,...n]=process.argv.slice(2);switch(e){case"run":return Un(n);case"bench":return Bn(n);case"compare":return Mn(n);case"report":return On(n);case"ci":return Ln(n);case"viz":return _n(n);case void 0:case"--help":case"-h":return process.stdout.write(`ostia - Bun-native profile IR engine
118
+ `),2;return await w(n,e.outDir),0}function me(t){let e=!1,r,o,n=!1,s=!1;for(let a=0;a<t.length;a++)switch(t[a]){case"--full":e=!0;break;case"--baseline":r=t[++a];break;case"--export-json":o=t[++a];break;case"--quiet":n=!0;break;case"--help":case"-h":s=!0;break}return{full:e,baseline:r,exportJson:o,quiet:n,help:s}}async function fe(t){let e=me(t);if(e.help)return process.stdout.write(te),0;let r=await B();if(!r)return process.stderr.write(`No ostia.config.json found. "ostia ci" needs configured workloads.
119
+ `),2;if(r.workloads.length===0)return process.stderr.write(`ostia.config.json has no "workloads" configured.
120
+ `),2;let o;try{o=await L({config:r,full:e.full,baselineName:e.baseline})}catch(n){if(n instanceof x)return process.stderr.write(`${n.message}
121
+ `),2;return process.stderr.write(`CI run failed: ${n instanceof Error?n.message:String(n)}
122
+ `),2}if(e.exportJson)await b(o.document,e.exportJson);if(!e.quiet)process.stdout.write(V(o.summary));return o.summary.regressed>0?1:0}async function he(){let[t,...e]=process.argv.slice(2);switch(t){case"run":return ne(e);case"bench":return oe(e);case"compare":return ie(e);case"report":return ce(e);case"ci":return fe(e);case"viz":return pe(e);case void 0:case"--help":case"-h":return process.stdout.write(`ostia - Bun-native profile IR engine
140
123
 
141
124
  Commands:
142
125
  run Run commands N times and report timing/CPU/heap
@@ -147,5 +130,5 @@ Commands:
147
130
  viz Render CPU evidence as collapsed/mermaid/speedscope/cpuprofile
148
131
 
149
132
  Run "ostia <command> --help" for details.
150
- `),e===void 0?2:0;default:return process.stderr.write(`Unknown subcommand "${e}". Run "ostia --help".
151
- `),2}}if(import.meta.main)Jn().then((e)=>process.exit(e));
133
+ `),t===void 0?2:0;default:return process.stderr.write(`Unknown subcommand "${t}". Run "ostia --help".
134
+ `),2}}if(import.meta.main)he().then((t)=>process.exit(t));
package/index.js CHANGED
@@ -1,19 +1,2 @@
1
1
  // @bun
2
- function A(e){return JSON.stringify(W(e))}function W(e){if(Array.isArray(e))return e.map(W);if(e!==null&&typeof e==="object"){let s={};for(let n of Object.keys(e).sort())s[n]=W(e[n]);return s}return e}function C(e,...s){let n=Bun.CryptoHasher.hash("sha256",A(s),"hex");return`${e}_${n.slice(0,16)}`}function Se(e){return e.startsWith("file://")?e.slice(7):e}function _(e,s,n){let r=e.nodes,t=r.length,a=new Map,i=[],o=new Map,c=new Int32Array(t);for(let p=0;p<t;p++){let f=r[p],u=f.callFrame,w=Se(u.url),k=a.get(u.functionName);if(k===void 0)k=new Map,a.set(u.functionName,k);let N=k.get(w);if(N===void 0)N=i.length,k.set(w,N),i.push({key:C("fr",u.functionName,w),name:u.functionName,url:w||void 0,line:u.lineNumber>=0?u.lineNumber:void 0,col:u.columnNumber>=0?u.columnNumber:void 0});c[p]=N,o.set(f.id,p)}let m=Array(t);for(let p=0;p<t;p++){let f=r[p];m[p]={id:f.id,frameIx:c[o.get(f.id)],children:f.children??[]}}let l=new Float64Array(t),d=new Float64Array(t),g=e.samples,x=e.timeDeltas;for(let p=0;p<g.length;p++){let f=o.get(g[p]);if(f===void 0)continue;l[f]+=x[p]??0,d[f]+=1}let R=new Int32Array(t).fill(-1);for(let p=0;p<t;p++){let f=r[p].children;if(!f)continue;for(let u of f){let w=o.get(u);if(w!==void 0)R[w]=p}}let y=[],b=[];for(let p=t-1;p>=0;p--)if(R[p]===-1)b.push(p);while(b.length>0){let p=b.pop();y.push(p);let f=r[p].children;if(!f)continue;for(let u of f){let w=o.get(u);if(w!==void 0&&R[w]===p)b.push(w)}}let T=new Float64Array(t);for(let p=y.length-1;p>=0;p--){let f=y[p];T[f]+=l[f];let u=R[f];if(u>=0)T[u]+=T[f]}let P=Array(i.length),h=[];for(let p=0;p<t;p++){let f=m[p].frameIx,u=P[f];if(u)u.selfUs+=l[p],u.totalUs+=T[p],u.samples+=d[p];else{let w={frameIx:f,selfUs:l[p],totalUs:T[p],samples:d[p]};P[f]=w,h.push(w)}}return{origin:s,samplingIntervalUs:n,frames:i,nodes:m,totals:h.sort((p,f)=>f.selfUs-p.selfUs),samples:{nodeIds:e.samples,timeDeltasUs:e.timeDeltas}}}function Me(e,s,n,r){let t=["--cpu-prof","--cpu-prof-dir",s,"--cpu-prof-name",n,"--cpu-prof-interval",String(r)],a=e[0];if(a==="bun"||a?.endsWith("/bun"))return[a,...t,...e.slice(1)];return e}async function ee(e){let s=`${e.artifactDir}/${e.fileName}`,n=e.argv[0],r=n==="bun"||n?.endsWith("/bun"),t=Me(e.argv,e.artifactDir,e.fileName,e.intervalUs),a=r?e.env:{...process.env,...e.env,BUN_OPTIONS:`--cpu-prof --cpu-prof-dir ${e.artifactDir} --cpu-prof-name ${e.fileName} --cpu-prof-interval ${e.intervalUs}`},i=Bun.nanoseconds(),c=await Bun.spawn(t,{cwd:e.cwd,env:a,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,m=Bun.nanoseconds()-i,l=Bun.file(s);if(!await l.exists())return{diagnosticWallNs:m,exitCode:c,warnings:[{code:"artifact-missing",message:`Expected a .cpuprofile at ${s} after exit ${c}, found nothing. The workload's argv[0] must be a \`bun\` binary for CPU capture.`,data:{artifactPath:s,argv:e.argv}}]};let d=await l.json(),g=_(d,"cpu-prof",e.intervalUs),x=d.samples.length===0?[{code:"empty-profile",message:"CPU capture produced zero samples."}]:[];return{diagnosticWallNs:m,exitCode:c,artifactPath:s,cpu:g,warnings:x}}function ne(e,s="heap-prof"){let{node_fields:n,node_types:r}=e.snapshot.meta,t=n.indexOf("type"),a=n.indexOf("self_size"),i=n.length,o=r[0];if(t===-1||a===-1||!Array.isArray(o))return{origin:s,typeCounts:[],objectCount:e.snapshot.node_count};let c=o.length,m=Array(c),l=new Map,d=[],g=0,x=e.nodes,R=x.length;for(let h=0;h<R;h+=i){let p=x[h+t],f=x[h+a]??0;g+=f;let u;if(p>=0&&p<c){if(u=m[p],u===void 0)u={type:o[p],count:0,bytes:0},m[p]=u,d.push(u)}else{let w=`unknown(${p})`;if(u=l.get(w),u===void 0)u={type:w,count:0,bytes:0},l.set(w,u),d.push(u)}u.count++,u.bytes+=f}let y=d.sort((h,p)=>p.count-h.count),b=y.slice(0,20),T=y.slice(20),P=b.map(({type:h,count:p,bytes:f})=>({type:h,count:p,retainedBytes:f}));if(T.length>0){let h=0,p=0;for(let f of T)h+=f.count,p+=f.bytes;P.push({type:"other",count:h,retainedBytes:p})}return{origin:s,heapSizeBytes:g,objectCount:e.snapshot.node_count,typeCounts:P}}function Be(e,s,n){let r=["--heap-prof","--heap-prof-dir",s,"--heap-prof-name",n],t=e[0];if(t==="bun"||t?.endsWith("/bun"))return[t,...r,...e.slice(1)];return e}async function te(e){let s=`${e.artifactDir}/${e.fileName}`,n=e.argv[0],r=n==="bun"||n?.endsWith("/bun"),t=Be(e.argv,e.artifactDir,e.fileName),a=r?e.env:{...process.env,...e.env,BUN_OPTIONS:`--heap-prof --heap-prof-dir ${e.artifactDir} --heap-prof-name ${e.fileName}`},i=Bun.nanoseconds(),c=await Bun.spawn(t,{cwd:e.cwd,env:a,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,m=Bun.nanoseconds()-i,l=Bun.file(s);if(!await l.exists())return{diagnosticWallNs:m,exitCode:c,warnings:[{code:"artifact-missing",message:`Expected a heap snapshot at ${s} after exit ${c}, found nothing. The workload's argv[0] must be a \`bun\` binary for heap capture.`,data:{artifactPath:s,argv:e.argv}}]};let d=await l.json(),g=ne(d,"heap-prof");return{diagnosticWallNs:m,exitCode:c,artifactPath:s,heap:g,warnings:[]}}import{Session as We}from"inspector/promises";var Oe=1000;async function re(e,s={}){let n=s.intervalUs??Oe,r=new We;r.connect();let t=Bun.nanoseconds();try{await r.post("Profiler.enable"),await r.post("Profiler.setSamplingInterval",{interval:n}),await r.post("Profiler.start");let a=await e(),{profile:i}=await r.post("Profiler.stop"),o=Bun.nanoseconds()-t,c=_(i,"inspector",n);return{result:a,cpu:c,diagnosticWallNs:o}}finally{r.disconnect()}}import{profile as Ae}from"bun:jsc";var Ee=new Map([["LLInt","llint"],["Baseline","baseline"],["DFG","dfg"],["FTL","ftl"]]),se=4294967295;function oe(e,s){let n=s??e.interval*1e6,r=new Map,t=[];function a(u,w,k,N){let I=r.get(u);if(I===void 0)I=new Map,r.set(u,I);let v=w??"",U=I.get(v);if(U===void 0)U=t.length,I.set(v,U),t.push({key:C("fr",u,v),name:u,url:w,line:k,col:N});return U}function i(u){let w=u.line===se,k=w?void 0:u.line-1,N=w||u.column===se?void 0:u.column-1;return a(u.name,u.sourceURL,k,N)}let o=a("(root)",void 0,void 0,void 0),c=1,m={id:0,frameIx:o,children:new Map,selfUs:0,samples:0,totalUs:0},l=new Map([[0,m]]),d={llint:0,baseline:0,dfg:0,ftl:0},g=new Map,x=[],R=[];for(let u of e.traces){let w=u.frames,k=m;for(let v=w.length-1;v>=0;v--){let U=i(w[v]),S=k.children.get(U);if(!S)S={id:c++,frameIx:U,children:new Map,selfUs:0,samples:0,totalUs:0},k.children.set(U,S),l.set(S.id,S);k=S}k.selfUs+=n,k.samples+=1,x.push(k.id),R.push(n);let N=w[0],I=N&&Ee.get(N.category);if(I){d[I]++;let v=g.get(I)??new Map;v.set(k.frameIx,(v.get(k.frameIx)??0)+1),g.set(I,v)}}function y(u){let w=u.selfUs;for(let k of u.children.values())w+=y(k);return u.totalUs=w,w}y(m);let b=new Map;function T(u){let w=b.get(u.frameIx);if(w)w.selfUs+=u.selfUs,w.totalUs+=u.totalUs,w.samples+=u.samples;else b.set(u.frameIx,{frameIx:u.frameIx,selfUs:u.selfUs,totalUs:u.totalUs,samples:u.samples});for(let k of u.children.values())T(k)}T(m);let P=[...l.values()].map((u)=>({id:u.id,frameIx:u.frameIx,children:[...u.children.values()].map((w)=>w.id)})),h={origin:"jsc-profile",samplingIntervalUs:n,frames:t,nodes:P,totals:[...b.values()].sort((u,w)=>w.selfUs-u.selfUs),samples:{nodeIds:x,timeDeltasUs:R}},p=[...g.entries()].flatMap(([u,w])=>[...w.entries()].sort((k,N)=>N[1]-k[1]).slice(0,3).map(([k,N])=>({tier:u,frameKey:t[k].key,samples:N})));return{cpu:h,jit:{origin:"jsc-profile",tiers:d,topFramesByTier:p}}}var _e=1000;async function ie(e,s={}){let n=s.intervalUs??_e,r,t=Bun.nanoseconds(),a=await Ae(async()=>(r=await e(),r),n),i=Bun.nanoseconds()-t,{cpu:o,jit:c}=oe(a.stackTraces,n);return{result:r,cpu:o,jit:c,diagnosticWallNs:i}}var V="0.1.0";function j(e,s){return{schemaVersion:1,toolVersion:V,bunVersion:Bun.version,platform:{os:process.platform,arch:process.arch},createdAt:new Date().toISOString(),workloads:e,runs:s}}function ae(e,s){return{id:C("wl","subprocess",e,process.cwd()),kind:"subprocess",command:e,label:s}}function ce(e,s){return{id:C("wl","inprocess",e.name,e.toString()),kind:"inprocess",label:s}}function ue(e){return{id:C("run",e.workload.id,"timing",e.configFingerprint,Bun.version,V),workloadId:e.workload.id,phase:"timing",instrumented:!1,configFingerprint:e.configFingerprint,trials:e.trials,timing:e.timing,warnings:e.warnings,artifacts:[],memory:je(e.trials)}}function je(e){let s=e.map((n)=>n.maxRssBytes).filter((n)=>n!==void 0);if(s.length===0)return;return{origin:"resourceUsage",perTrial:e.map((n)=>({rssBytes:n.maxRssBytes})),maxRssBytes:Math.max(...s)}}function L(e){return{id:C("run",e.workload.id,e.phase,e.configFingerprint,Bun.version,V),workloadId:e.workload.id,phase:e.phase,instrumented:!0,configFingerprint:e.configFingerprint,trials:[{i:0,wallNs:e.diagnosticWallNs,exitCode:e.exitCode}],diagnosticWallNs:e.diagnosticWallNs,cpu:e.cpu,heap:e.heap,jit:e.jit,warnings:e.warnings,artifacts:e.artifacts}}async function pe(e,s,n){let t=await Bun.file(n).arrayBuffer(),a=new Bun.CryptoHasher("sha256");return a.update(t),{id:C("art",e,s,n),kind:s,path:n,sha256:a.digest("hex"),bytes:t.byteLength}}function K(e){return C("cfg",e)}function q(e){return`${JSON.stringify(W(e),null,2)}
3
- `}async function Le(e,s){await Bun.write(s,q(e))}async function G(e){let s=await Bun.file(e).text();return JSON.parse(s)}async function Y(e){let s=Bun.nanoseconds(),n=Bun.spawn(e.argv,{cwd:e.cwd,env:e.env,stdout:"ignore",stderr:"ignore",stdin:"ignore"}),r=await n.exited,t=Bun.nanoseconds(),a=n.resourceUsage?.();return{wallNs:t-s,exitCode:r,userNs:a?Number(a.cpuTime.user)*1000:void 0,systemNs:a?Number(a.cpuTime.system)*1000:void 0,maxRssBytes:a?.maxRSS}}function le(e){return e.trim().split(/\s+/).filter(Boolean)}function me(e){if(e.length===0)throw Error("computeTimingStats: samples must be non-empty");let s=e.length,n=de(e),r=0;for(let h=0;h<s;h++)r+=e[h];let t=r/s,a=O(n,0.5),i=0;for(let h=0;h<s;h++){let p=e[h]-t;i+=p*p}let o=Math.sqrt(i/s),c=n[0],m=n[s-1],l=O(n,0.25),d=O(n,0.75),g=d-l,x=l-1.5*g,R=d+1.5*g,y=l-3*g,b=d+3*g,T=0,P=0;for(let h=0;h<s;h++){let p=e[h];if(p<y||p>b)P++;else if(p<x||p>R)T++}return{unit:"ns",samples:e,mean:t,median:a,stddev:o,min:c,max:m,outliers:{mild:T,severe:P}}}function de(e){let s=new Float64Array(e.length);return s.set(e),s.sort(),s}function O(e,s){let n=e.length;if(n===1)return e[0];let r=s*(n-1),t=Math.floor(r),a=Math.ceil(r);if(t===a)return e[t];let i=r-t;return e[t]*(1-i)+e[a]*i}var He=5000000,Je=200;function fe(e,s,n="subprocess"){let r=[],t=e.samples[0];if(t!==void 0){let i=de(e.samples),o=O(i,0.25),m=O(i,0.75)-o;if(t>e.median+3*m&&m>0)r.push({code:"slow-first-run",message:`First run took ${(t/1e6).toFixed(2)}ms, much slower than the median ${(e.median/1e6).toFixed(2)}ms. Consider more warmup.`,data:{firstNs:t,medianNs:e.median}})}if(e.outliers.mild+e.outliers.severe>0)r.push({code:"outliers-detected",message:`${e.outliers.mild+e.outliers.severe} outlier(s) detected (${e.outliers.severe} severe, ${e.outliers.mild} mild).`,data:e.outliers});if(n==="subprocess"&&e.median<He)r.push({code:"fast-command",message:`Median run time (${(e.median/1e6).toFixed(3)}ms) is very fast; results may be dominated by spawn overhead.`,data:{medianNs:e.median}});if(n==="inprocess"&&e.median<Je)r.push({code:"below-timer-resolution",message:`Median run time (${e.median.toFixed(0)}ns) is close to timer resolution; consider a larger batch size or a coarser operation.`,data:{medianNs:e.median}});let a=s.filter((i)=>i!==void 0&&i!==0);if(a.length>0)r.push({code:"nonzero-exit",message:`${a.length} of ${s.length} trial(s) exited non-zero.`,data:{exitCodes:a}});return r}var ze=10,Ve=3000000000,Ke=3;async function ge(e){let s=e.warmup??Ke;for(let l=0;l<s;l++)await Y(e);let n=[],r=e.runs??e.minRuns??ze,t=e.runs!==void 0?0:e.minTotalNs??Ve,a=0,i=0;while(i<r||a<t){let l=await Y(e);if(n.push({i,wallNs:l.wallNs,exitCode:l.exitCode,userNs:l.userNs,systemNs:l.systemNs,maxRssBytes:l.maxRssBytes}),a+=l.wallNs,i++,e.runs!==void 0&&i>=e.runs)break}let o=n.map((l)=>l.wallNs),c=me(o),m=fe(c,n.map((l)=>l.exitCode));return{trials:n,timing:c,warnings:m}}var qe=new URL("./runner.ts",import.meta.url).pathname,Ge=".ostia";async function Ye(e){let n=`${e.outDir??Ge}/bench-tmp`,r=e.cwd??process.cwd(),t={timeBudgetMs:e.timeBudgetMs,minSamples:e.minSamples,gc:e.gc},a=[],i=[];try{for(let o of e.suites){let c=o.startsWith("/")?o:`${r}/${o}`,m=`${n}/${C("bench-out",c)}.json`,d=await Bun.spawn(["bun",qe,c,m,JSON.stringify(t)],{cwd:r,stdout:"inherit",stderr:"inherit",stdin:"ignore"}).exited;if(d!==0)throw Error(`Bench suite failed: ${o} (runner exited ${d})`);let g=await G(m);a.push(...g.workloads),i.push(...g.runs)}}finally{await Bun.spawn(["rm","-rf",n]).exited}return j(a,i)}var Ze=[],H;function Qe(e,s){let n=H;H=e;try{s()}finally{H=n}}function Xe(e,s){Ze.push({groupName:H,name:e,fn:s})}var he={timingPct:5,frameSelfPct:10,heapTypePct:10,minFrameSelfUs:1000};function J(e,s){if(e===0)return s===0?0:1/0;return(s-e)/e*100}function M(e,s,n){return e.runs.find((r)=>r.workloadId===s&&r.phase===n)}function en(e,s,n=he){let r=new Set(s.workloads.map((a)=>a.id)),t=[];for(let a of e.workloads){if(!r.has(a.id))continue;let i=nn(e,s,a.id,n);if(i)t.push(i)}return t}function nn(e,s,n,r=he){let t=M(e,n,"timing"),a=M(s,n,"timing"),i=M(e,n,"cpu"),o=M(s,n,"cpu"),c=M(e,n,"heap"),m=M(s,n,"heap"),l=t?.id??i?.id??c?.id,d=a?.id??o?.id??m?.id;if(!l||!d)return;let g=!1,x;if(t?.timing&&a?.timing){let b=J(t.timing.median,a.timing.median),T=J(t.timing.mean,a.timing.mean),P=b>r.timingPct?"regressed":b<-r.timingPct?"improved":"unchanged";if(P==="regressed")g=!0;x={medianDeltaPct:b,meanDeltaPct:T,verdict:P}}let R;if(i?.cpu&&o?.cpu){let b=new Map(i.cpu.totals.map((f)=>[i.cpu.frames[f.frameIx].key,f])),T=new Map(o.cpu.totals.map((f)=>[o.cpu.frames[f.frameIx].key,f])),P=new Map(i.cpu.frames.map((f)=>[f.key,f.name])),h=new Map(o.cpu.frames.map((f)=>[f.key,f.name]));R=[...new Set([...b.keys(),...T.keys()])].map((f)=>{let u=b.get(f)?.selfUs??0,w=T.get(f)?.selfUs??0;return{frameKey:f,name:h.get(f)??P.get(f)??f,baseSelfUs:u,candSelfUs:w,deltaPct:J(u,w)}}).sort((f,u)=>Math.abs(u.deltaPct)-Math.abs(f.deltaPct));for(let f of R)if((f.baseSelfUs>=r.minFrameSelfUs||f.candSelfUs>=r.minFrameSelfUs)&&f.deltaPct>r.frameSelfPct)g=!0}let y;if(c?.heap&&m?.heap){let b=new Map(c.heap.typeCounts.map((h)=>[h.type,h])),T=new Map(m.heap.typeCounts.map((h)=>[h.type,h]));y=[...new Set([...b.keys(),...T.keys()])].map((h)=>{let p=b.get(h),f=T.get(h);return{type:h,baseCount:p?.count??0,candCount:f?.count??0,baseBytes:p?.retainedBytes,candBytes:f?.retainedBytes,deltaPct:J(p?.count??0,f?.count??0)}}).sort((h,p)=>Math.abs(p.deltaPct)-Math.abs(h.deltaPct));for(let h of y)if(h.deltaPct>r.heapTypePct)g=!0}return{id:C("cmp",l,d),baselineRunId:l,candidateRunId:d,timing:x,frames:R,heapTypes:y,thresholds:r,verdict:g?"fail":"pass"}}function F(e,s){if(s){let n=e.runs.find((r)=>r.id===s);return n?.cpu?[n]:[]}return e.runs.filter((n)=>n.phase==="cpu"&&n.cpu)}function B(e){let s=e.nodes,n=s.length,r=tn(e),t=new Int32Array(n).fill(-1);for(let c=0;c<n;c++)for(let m of s[c].children){let l=r(m);if(l!==-1)t[l]=c}let a=[];for(let c=0;c<n;c++)if(t[c]===-1)a.push(c);let i=[],o=[];for(let c=a.length-1;c>=0;c--)o.push(a[c]);while(o.length>0){let c=o.pop();i.push(c);for(let m of s[c].children){let l=r(m);if(l!==-1&&t[l]===c)o.push(l)}}return{count:n,indexOf:r,parentIx:t,roots:a,order:i}}function tn(e){let s=e.nodes,n=s.length,r=1/0,t=-1/0,a=!0;for(let o=0;o<n;o++){let c=s[o].id;if(!Number.isInteger(c)){a=!1;break}if(c<r)r=c;if(c>t)t=c}if(a&&n>0&&t-r<n*4+64){let o=t-r+1,c=new Int32Array(o).fill(-1);for(let m=0;m<n;m++)c[s[m].id-r]=m;return(m)=>{let l=m-r;return l>=0&&l<o?c[l]:-1}}let i=new Map;for(let o=0;o<n;o++)i.set(s[o].id,o);return(o)=>i.get(o)??-1}function ye(e,s){let{count:n,indexOf:r,parentIx:t,order:a}=s,i=new Float64Array(n),o=new Float64Array(n),c=e.samples?.nodeIds??[],m=e.samples?.timeDeltasUs??[];for(let d=0;d<c.length;d++){let g=r(c[d]);if(g===-1)continue;i[g]+=m[d]??0,o[g]+=1}let l=new Float64Array(n);for(let d=a.length-1;d>=0;d--){let g=a[d];l[g]+=i[g];let x=t[g];if(x>=0)l[x]+=l[g]}return{selfUs:i,totalUs:l,samples:o}}var we={name:"collapsed",async render(e,s={}){return{files:F(e,s.runId).map((t)=>{let a=t.cpu,{nodes:i,frames:o}=a,c=B(a),m=Array(c.count);for(let R of c.order){let y=o[i[R].frameIx].name||"(anonymous)",b=c.parentIx[R];m[R]=b===-1?y:`${m[b]};${y}`}let l=new Float64Array(c.count),d=[],g=a.samples?.nodeIds??[];for(let R=0;R<g.length;R++){let y=c.indexOf(g[R]);if(y===-1)continue;if(l[y]++===0)d.push(y)}let x=Array(d.length);for(let R=0;R<d.length;R++){let y=d[R];x[R]=`${m[y]} ${l[y]}`}return{path:`${t.id}.collapsed.txt`,content:x.join(`
4
- `)+(x.length>0?`
5
- `:"")}})}}};var be={name:"cpuprofile",async render(e,s={}){let n=F(e,s.runId),r=[],t=[];for(let a of n){if(a.cpu?.origin!=="cpu-prof"&&a.cpu?.origin!=="inspector"){t.push(`${a.id} (origin ${a.cpu?.origin??"unknown"} has no .cpuprofile artifact to pass through)`);continue}let i=a.artifacts.find((c)=>c.kind==="cpuprofile");if(!i){t.push(`${a.id} (no cpuprofile artifact recorded on this run)`);continue}let o=Bun.file(i.path);if(!await o.exists()){t.push(`${a.id} (artifact missing on disk: ${i.path})`);continue}r.push({path:`${a.id}.cpuprofile`,content:await o.text()})}if(r.length===0&&t.length>0)return{text:`No .cpuprofile artifacts available:
6
- ${t.map((a)=>` - ${a}`).join(`
7
- `)}
8
- `};return{files:r}}};var xe={name:"json",async render(e){return{text:q(e)}}};var Re={name:"jsonl",async render(e){let{runs:s,...n}=e;return{text:`${[A(n),...s.map((t)=>A(t))].join(`
9
- `)}
10
- `}}};function D(e){return(e/1e6).toFixed(3)}function z(e){return e?.label??e?.command?.join(" ")??e?.entry?.task??e?.id??"unknown"}var Te=10,Pe=10,ke={name:"markdown",async render(e){let s=new Map(e.workloads.map((t)=>[t.id,t])),n=[];n.push("# Profile Report",""),n.push(`Bun ${e.bunVersion} \xB7 ostia ${e.toolVersion} \xB7 ${e.platform.os}/${e.platform.arch} \xB7 ${e.createdAt}`,"");let r=e.runs.filter((t)=>t.phase==="timing"&&t.timing!==void 0);if(r.length>0){n.push("## Timing",""),n.push("| Command | Mean \xB1 SD (ms) | Min\u2026Max (ms) | Median (ms) |","|---|---|---|---|");for(let a of r){let i=z(s.get(a.workloadId)),o=a.timing;n.push(`| ${i} | ${D(o.mean)} \xB1 ${D(o.stddev)} | ${D(o.min)}\u2026${D(o.max)} | ${D(o.median)} |`)}n.push("");let t=r.filter((a)=>a.warnings.length>0);if(t.length>0){n.push("### Warnings","");for(let a of t){let i=z(s.get(a.workloadId));for(let o of a.warnings)n.push(`- **${i}**: ${o.message} (\`${o.code}\`)`)}n.push("")}}for(let t of e.runs){if(t.phase!=="cpu"&&t.phase!=="heap")continue;let a=z(s.get(t.workloadId));if(t.phase==="cpu"){if(n.push(`## CPU capture - ${a}`,""),n.push(`instrumented, diagnostic wall ${D(t.diagnosticWallNs??0)}ms`,""),t.cpu){n.push(`origin: \`${t.cpu.origin}\`, interval: ${t.cpu.samplingIntervalUs}\xB5s`,""),n.push("| Self % | Self (ms) | Total (ms) | Frame |","|---|---|---|---|");let i=t.cpu.totals.reduce((o,c)=>o+c.selfUs,0)||1;for(let o of t.cpu.totals.slice(0,Te)){let c=t.cpu.frames[o.frameIx],m=(o.selfUs/i*100).toFixed(1);n.push(`| ${m}% | ${(o.selfUs/1000).toFixed(2)} | ${(o.totalUs/1000).toFixed(2)} | ${c?.name||"(anonymous)"} |`)}if(n.push(""),t.jit){let o=t.jit.tiers;n.push(`JIT tiers: LLInt ${o.llint} \xB7 Baseline ${o.baseline} \xB7 DFG ${o.dfg} \xB7 FTL ${o.ftl}`,"")}}}else if(n.push(`## Heap snapshot - ${a}`,""),n.push(`instrumented, diagnostic wall ${D(t.diagnosticWallNs??0)}ms`,""),t.heap){n.push(`${t.heap.objectCount??"?"} objects, ${((t.heap.heapSizeBytes??0)/1e6).toFixed(2)}MB`,""),n.push("| Count | Type |","|---|---|");for(let i of t.heap.typeCounts.slice(0,Pe))n.push(`| ${i.count} | ${i.type} |`);n.push("")}for(let i of t.artifacts)n.push(`- artifact: \`${i.path}\``);for(let i of t.warnings)n.push(`- ! ${i.message} (\`${i.code}\`)`);if(t.artifacts.length>0||t.warnings.length>0)n.push("")}if(e.comparisons&&e.comparisons.length>0){n.push("## Comparisons","");for(let t of e.comparisons){let a=e.runs.find((o)=>o.id===t.candidateRunId),i=z(a?s.get(a.workloadId):void 0);if(n.push(`### ${t.verdict==="pass"?"\u2713":"\u2717"} ${i}`,""),t.timing){let o=t.timing.medianDeltaPct>0?"+":"";n.push(`- timing: ${o}${t.timing.medianDeltaPct.toFixed(1)}% median (**${t.timing.verdict}**)`)}for(let o of t.frames?.slice(0,Te)??[]){if(Math.abs(o.deltaPct)<0.5)continue;let c=o.deltaPct>0?"+":"";n.push(`- frame \`${o.name}\`: ${c}${o.deltaPct.toFixed(1)}% self-time (${(o.baseSelfUs/1000).toFixed(2)}ms \u2192 ${(o.candSelfUs/1000).toFixed(2)}ms)`)}for(let o of t.heapTypes?.slice(0,Pe)??[]){if(Math.abs(o.deltaPct)<0.5)continue;let c=o.deltaPct>0?"+":"";n.push(`- heap \`${o.type}\`: ${c}${o.deltaPct.toFixed(1)}% count (${o.baseCount} \u2192 ${o.candCount})`)}n.push("")}}return{text:n.join(`
11
- `)}}};var rn=15;function Z(e){return`n${e}`}function sn(e,s,n){return`${(e||"(anonymous)").replace(/"/g,"'")} (self ${(s/1000).toFixed(2)}ms, total ${(n/1000).toFixed(2)}ms)`}function on(e,s,n,r){let t=[];if(r<=0)return t;for(let a=0;a<s;a++){if(a===n)continue;let i=e[a];if(t.length===r&&i<=e[t[r-1]])continue;let o=t.length;while(o>0&&e[t[o-1]]<i)o--;if(t.splice(o,0,a),t.length>r)t.pop()}return t}var $e={name:"mermaid",async render(e,s={}){let n=s.topN??rn;return{files:F(e,s.runId).map((a)=>{let i=a.cpu,{nodes:o,frames:c}=i,m=B(i),{selfUs:l,totalUs:d}=ye(i,m),{parentIx:g}=m,x=m.roots[0]??-1,R=on(l,m.count,x,n),y=new Set(x!==-1?[x]:[]),b=[];for(let P of R){b.length=0;for(let h=P;h!==-1;h=g[h])b.push(h);for(let h=b.length-1;h>=0;h--)y.add(b[h])}let T=["graph TD"];for(let P of y){let h=o[P].id;T.push(` ${Z(h)}["${sn(c[o[P].frameIx].name,l[P],d[P])}"]`)}for(let P of y){let h=g[P];if(h!==-1&&y.has(h))T.push(` ${Z(o[h].id)} --> ${Z(o[P].id)}`)}return{path:`${a.id}.mermaid.md`,content:`${T.join(`
12
- `)}
13
- `}})}}};var an="https://www.speedscope.app/file-format-schema.json";function Ne(e){return e?.label??e?.command?.join(" ")??e?.entry?.task??"profile"}var Ce={name:"speedscope",async render(e,s={}){let n=F(e,s.runId),r=new Map(e.workloads.map((a)=>[a.id,a]));return{files:n.map((a)=>{let i=a.cpu,{nodes:o}=i,c=B(i),m=i.samples?.nodeIds??[],l=i.samples?.timeDeltasUs??[],d=Array(c.count);for(let y of c.order){let b=c.parentIx[y],T=o[y].frameIx;d[y]=b===-1?[T]:[...d[b],T]}let g=Array(m.length);for(let y=0;y<m.length;y++){let b=c.indexOf(m[y]);g[y]=b===-1?[]:d[b]}let x=0;for(let y=0;y<l.length;y++)x+=l[y];let R={$schema:an,exporter:"ostia",name:Ne(r.get(a.workloadId)),activeProfileIndex:0,shared:{frames:i.frames.map((y)=>({name:y.name||"(anonymous)",file:y.url,line:y.line!==void 0?y.line+1:void 0}))},profiles:[{type:"sampled",name:Ne(r.get(a.workloadId)),unit:"microseconds",startValue:0,endValue:x,samples:g,weights:l}]};return{path:`${a.id}.speedscope.json`,content:`${JSON.stringify(R,null,2)}
14
- `}})}}};function E(e){return(e/1e6).toFixed(3)}function Q(e){return e.label??e.command?.join(" ")??e.entry?.task??e.id}var Ie={name:"table",async render(e){let s=e.runs.filter((d)=>d.phase==="timing"&&d.timing!==void 0),n=new Map(e.workloads.map((d)=>[d.id,d]));if(s.length===0){let d=ve(e,n);return{text:d.length>0?`${d.join(`
15
- `)}
16
- `:`(no timing runs)
17
- `}}let r=s.map((d)=>{let g=n.get(d.workloadId);return{run:d,workload:g,label:g?Q(g):d.workloadId}}),t=Math.min(...r.map((d)=>d.run.timing.median)),a=r.length>1,i=[],o=Math.max(7,...r.map((d)=>d.label.length)),c=a?`${"Command".padEnd(o)} Mean [ms] Min\u2026Max [ms] Relative`:`${"Command".padEnd(o)} Mean [ms] Min\u2026Max [ms]`;i.push(c),i.push("-".repeat(c.length));for(let{run:d,label:g}of r){let x=d.timing,R=`${E(x.mean)} \xB1 ${E(x.stddev)}`,y=`${E(x.min)}\u2026${E(x.max)}`,b=`${g.padEnd(o)} ${R.padEnd(15)} ${y.padEnd(18)}`;if(a){let T=x.median/t;b+=T===1?" 1.00\xD7":` ${T.toFixed(2)}\xD7 slower`}i.push(b);for(let T of d.warnings)i.push(` ! ${T.message}`)}let m=un(e,n);if(m.length>0)i.push(""),i.push(...m);let l=ve(e,n);if(l.length>0)i.push(""),i.push(...l);return{text:`${i.join(`
18
- `)}
19
- `}}};function cn(e,s,n){let r=e.runs.find((a)=>a.id===n),t=r?s.get(r.workloadId):void 0;return t?Q(t):n}function ve(e,s){if(!e.comparisons||e.comparisons.length===0)return[];let n=[];for(let r of e.comparisons){let t=cn(e,s,r.candidateRunId),a=r.verdict==="pass"?"\u2713":"\u2717";if(n.push(`${a} ${t}`),r.timing){let i=r.timing.medianDeltaPct>0?"+":"";n.push(` timing: ${i}${r.timing.medianDeltaPct.toFixed(1)}% median (${r.timing.verdict})`)}if(r.frames)for(let i of r.frames.slice(0,Ue)){if(Math.abs(i.deltaPct)<0.5)continue;let o=i.deltaPct>0?"+":"";n.push(` frame ${i.name}: ${o}${i.deltaPct.toFixed(1)}% self-time (${(i.baseSelfUs/1000).toFixed(2)}ms -> ${(i.candSelfUs/1000).toFixed(2)}ms)`)}if(r.heapTypes)for(let i of r.heapTypes.slice(0,Fe)){if(Math.abs(i.deltaPct)<0.5)continue;let o=i.deltaPct>0?"+":"";n.push(` heap ${i.type}: ${o}${i.deltaPct.toFixed(1)}% count (${i.baseCount} -> ${i.candCount})`)}}return n}var Ue=5,Fe=5;function un(e,s){let n=[];for(let r of e.runs){if(r.phase!=="cpu"&&r.phase!=="heap")continue;let t=s.get(r.workloadId),a=t?Q(t):r.workloadId;if(r.phase==="cpu")if(r.cpu){n.push(`CPU capture - ${a} (instrumented, ${r.cpu.samplingIntervalUs}\xB5s interval, diagnostic wall ${E(r.diagnosticWallNs??0)}ms)`);let i=r.cpu.totals.reduce((o,c)=>o+c.selfUs,0)||1;for(let o of r.cpu.totals.slice(0,Ue)){let c=r.cpu.frames[o.frameIx],m=(o.selfUs/i*100).toFixed(1);n.push(` ${m.padStart(5)}% ${(o.selfUs/1000).toFixed(2).padStart(8)}ms self ${c?.name??"?"}`)}}else n.push(`CPU capture - ${a} (instrumented, no evidence captured)`);else if(r.heap){let i=((r.heap.heapSizeBytes??0)/1e6).toFixed(2);n.push(`Heap snapshot - ${a} (instrumented, ${r.heap.objectCount??"?"} objects, ${i}MB)`);for(let o of r.heap.typeCounts.slice(0,Fe))n.push(` ${String(o.count).padStart(6)} ${o.type}`)}else n.push(`Heap snapshot - ${a} (instrumented, no evidence captured)`);for(let i of r.artifacts)n.push(` artifact: ${i.path}`);for(let i of r.warnings)n.push(` ! ${i.message}`)}return n}var pn={table:Ie,json:xe,markdown:ke,jsonl:Re,collapsed:we,mermaid:$e,speedscope:Ce,cpuprofile:be};var ln=".ostia",X=1000;async function wt(e){let s=K({runs:e.runs??null,warmup:e.warmup??null,cpu:e.cpu??!1,heap:e.heap??!1,cpuIntervalUs:e.cpuIntervalUs??X}),r=`${e.outDir??ln}/artifacts`,t=[],a=[];for(let i of e.commands){let o=Array.isArray(i)?i:le(i),c=ae(o,Array.isArray(i)?void 0:i);t.push(c);let m=await ge({argv:o,cwd:e.cwd,env:e.env,runs:e.runs,warmup:e.warmup}),l=ue({workload:c,configFingerprint:s,trials:m.trials,timing:m.timing,warnings:m.warnings});if(a.push(l),e.cpu){let d=`${l.id}-cpu.cpuprofile`,g=await ee({argv:o,cwd:e.cwd,env:e.env,artifactDir:r,fileName:d,intervalUs:e.cpuIntervalUs??X});a.push(await De({workload:c,phase:"cpu",configFingerprint:s,diagnosticWallNs:g.diagnosticWallNs,exitCode:g.exitCode,cpu:g.cpu,artifactPath:g.artifactPath,artifactKind:"cpuprofile",warnings:g.warnings}))}if(e.heap){let d=`${l.id}-heap.heapsnapshot`,g=await te({argv:o,cwd:e.cwd,env:e.env,artifactDir:r,fileName:d});a.push(await De({workload:c,phase:"heap",configFingerprint:s,diagnosticWallNs:g.diagnosticWallNs,exitCode:g.exitCode,heap:g.heap,artifactPath:g.artifactPath,artifactKind:"heapsnapshot",warnings:g.warnings}))}}return j(t,a)}async function De(e){let s=`${e.workload.id}-${e.phase}-${e.configFingerprint}`,n=e.artifactPath?[await pe(s,e.artifactKind,e.artifactPath)]:[];return L({workload:e.workload,phase:e.phase,configFingerprint:e.configFingerprint,diagnosticWallNs:e.diagnosticWallNs,exitCode:e.exitCode,cpu:e.cpu,heap:e.heap,warnings:e.warnings,artifacts:n})}async function bt(e,s={}){let n=ce(e),r=K({intervalUs:s.intervalUs??X,origin:s.origin??"inspector"}),t=(m)=>m.samples?.nodeIds.length===0?[{code:"empty-profile",message:"In-process capture produced zero samples."}]:[];if(s.origin==="jsc"){let{result:m,cpu:l,jit:d,diagnosticWallNs:g}=await ie(e,s),x=L({workload:n,phase:"cpu",configFingerprint:r,diagnosticWallNs:g,cpu:l,jit:d,warnings:t(l),artifacts:[]});return{result:m,run:x}}let{result:a,cpu:i,diagnosticWallNs:o}=await re(e,s),c=L({workload:n,phase:"cpu",configFingerprint:r,diagnosticWallNs:o,cpu:i,warnings:t(i),artifacts:[]});return{result:a,run:c}}export{Ye as bench,en as compareDocuments,Qe as group,G as loadDocument,bt as profile,pn as renderers,wt as run,Le as saveDocument,Xe as task};
2
+ import{a as c,c as d,f as g,g as h,h as i}from"./chunk-j0j2b0fj.js";import{u as a,v as b,y as e,z as f}from"./chunk-ck12vbed.js";export{c as bench,d as compareDocuments,e as group,b as loadDocument,i as profile,g as renderers,h as run,a as saveDocument,f as task};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ostia",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Fast profiling and benchmarking for Bun.",
5
5
  "type": "module",
6
6
  "exports": {
package/runner.ts ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bun
2
+ // @bun
3
+ import{A as P,B as E,l as M,o as F,p as N,s as y,u as I,w as B,x as h}from"./chunk-ck12vbed.js";var A=500,D=20,O=0.1,k=1000,S=0;function d(n){if(typeof n==="number")S+=n;else if(n!==void 0&&n!==null)S+=1}function x(n){return n!==null&&typeof n==="object"&&typeof n.then==="function"}async function b(n,t={}){let r=(t.timeBudgetMs??A)*1e6,e=t.minSamples??D,c=r*(t.warmupFraction??O),p=Bun.nanoseconds();while(Bun.nanoseconds()-p<c)d(await n());let m=Bun.nanoseconds();d(await n());let a=Math.max(1,Bun.nanoseconds()-m),s=a<k?Math.max(1,Math.ceil(k/a)):1,i=[],u=Bun.nanoseconds(),o=0,l=0;while(l<e||o<r){let g=Bun.nanoseconds();for(let T=0;T<s;T++){let w=n();d(x(w)?await w:w)}let R=Bun.nanoseconds();if(i.push({i:l,wallNs:(R-g)/s}),l++,o=Bun.nanoseconds()-u,t.gc)Bun.gc(!0)}let _=i.map((g)=>g.wallNs),f=B(_),L=h(f,[],"inprocess");return{trials:i,timing:f,warnings:L}}async function U(){let[n,t,r]=process.argv.slice(2);if(!n||!t)return process.stderr.write(`bench runner: usage: runner.ts <suiteFile> <outputPath> [optsJson]
4
+ `),2;let e=r?JSON.parse(r):{};E(),await import(n);let c=P();if(c.length===0)return process.stderr.write(`bench runner: ${n} registered no tasks (no task() calls found).
5
+ `),2;let p=y({timeBudgetMs:e.timeBudgetMs??null,minSamples:e.minSamples??null,gc:e.gc??!1}),m=[],a=[];for(let s of c){let i=s.groupName?`${s.groupName}/${s.name}`:s.name,u=F(n,i,i);m.push(u);let o=await b(s.fn,e);a.push(N({workload:u,configFingerprint:p,trials:o.trials,timing:o.timing,warnings:o.warnings}))}return await I(M(m,a),t),0}U().then((n)=>process.exit(n));