function w(n){return new d(n)}class d{base;probeTimeout;pollInterval;_state="unknown";constructor(t){if(t?.baseUrl)this.base=t.baseUrl.replace(/\/$/,"");else{const e=t?.port??43115;this.base=`http://127.0.0.1:${e}`}this.probeTimeout=t?.probeTimeout??2e3,this.pollInterval=t?.pollInterval??500}get state(){return this._state}get isConnected(){return this._state==="connected"}async probe(){this._state="probing";try{const e=await(await this.fetch("/health",{timeout:this.probeTimeout})).json();return this._state=e.ok?"connected":"unavailable",e.ok}catch{return this._state="unavailable",!1}}async health(){return(await this.fetch("/health")).json()}async capabilities(){return(await this.fetch("/capabilities")).json()}async transcribe(t){const{audio:e,format:o,language:s,timestamps:c,metadata:i}=t,a=new FormData;if(e instanceof Blob){const u=o??f(e.type)??"wav";a.append("audio",e,`audio.${u}`)}else{const u=o??"wav",h=new Blob([e],{type:b(u)});a.append("audio",h,`audio.${u}`)}return o&&a.append("format",o),s&&a.append("language",s),c&&a.append("timestamps","true"),i&&a.append("metadata",JSON.stringify(i)),(await this.fetch("/transcribe",{method:"POST",body:a})).json()}async createJob(t){return(await this.fetch("/jobs",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).json()}async getJob(t){return(await this.fetch(`/jobs/${t}`)).json()}async align(t){const{jobId:e}=await this.createJob({...t,type:"alignment"});return this.waitForJob(e)}launch(){window.location.href="vox://launch"}openSettings(){window.location.href="vox://settings"}async waitForJob(t){for(let o=0;o<600;o++){const s=await this.getJob(t);if(s.status==="completed"){if(!s.result?.alignment)throw new r("Job completed but no alignment result","no_result");return s.result.alignment}if(s.status==="failed")throw new r(s.error??"Job failed","job_failed");await p(this.pollInterval)}throw new r("Job timed out","timeout")}async fetch(t,e){const{timeout:o,...s}=e??{},c=new AbortController,i=o?setTimeout(()=>c.abort(),o):void 0;try{const a=await globalThis.fetch(`${this.base}${t}`,{...s,signal:c.signal});if(!a.ok){const l=await a.text().catch(()=>"");throw new r(`${a.status} ${a.statusText}: ${l}`,"http_error")}return a}catch(a){throw a instanceof r?a:new r(a instanceof Error?a.message:"Companion unreachable","network_error")}finally{i&&clearTimeout(i)}}}class r extends Error{code;constructor(t,e){super(t),this.code=e,this.name="VoxDError"}}function p(n){return new Promise(t=>setTimeout(t,n))}function f(n){if(n.includes("mp3")||n.includes("mpeg"))return"mp3";if(n.includes("wav"))return"wav";if(n.includes("aac")||n.includes("mp4"))return"aac";if(n.includes("opus")||n.includes("ogg"))return"opus"}function b(n){switch(n){case"mp3":return"audio/mpeg";case"wav":return"audio/wav";case"aac":return"audio/aac";case"opus":return"audio/ogg; codecs=opus";case"pcm16":return"audio/pcm";default:return"application/octet-stream"}}export{d as VoxDClient,r as VoxDError,w as createVoxdClient};
