"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.xfetch=xfetch,exports.isXBindSupported=isXBindSupported,exports.getXBindCapability=getXBindCapability;const agent_js_1=require("./agent.js"),agent_call_js_1=require("./agent-call.js");async function checkXBindSupport(t){try{const e=await fetch(t,{method:"OPTIONS",headers:{"X-Capability-Check":"xbind"}});return"true"===e.headers.get("X-xBind-Support")?{supported:!0,endpoint:e.headers.get("X-xBind-Endpoint")||void 0,peerDID:e.headers.get("X-xBind-DID")||void 0,version:e.headers.get("X-xBind-Version")||void 0}:{supported:!1}}catch{return{supported:!1}}}async function sendViaXBind(t,e,r,n){const o=Date.now();if(!e.peerDID)throw new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.NETWORK_ERROR,"Server supports xBind but did not provide X-xBind-DID header",{url:t,capability:e});const a=e.peerDID,i=e.endpoint||t,s=new Uint8Array(16);crypto.getRandomValues(s);const c=Array.from(s).map(t=>t.toString(16).padStart(2,"0")).join(""),d=`xfetch_${Date.now()}_${c}`,l={correlationId:d,method:r.method||"GET",url:t,headers:r.headers||{},body:r.body?"string"==typeof r.body?r.body:JSON.stringify(r.body):void 0};return new Promise((e,s)=>{const c=setTimeout(()=>{s(new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.TIMEOUT,"xBind request timed out waiting for response",{url:t,correlationId:d,timeout:r.timeout||3e4}))},r.timeout||3e4);(async()=>{try{const p=await n.send({to:a,payload:l,scope:"xfetch",action:"http_request"});if(!p.ok)return clearTimeout(c),void s(new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.NETWORK_ERROR,`Failed to send xBind request: ${p.error}`,{url:t,error:p.error}));const u=`${i}/response/${d}`,_=100,g=(r.timeout||3e4)/_;for(let t=0;t<g;t++){await new Promise(t=>setTimeout(t,_));try{const t=await fetch(u);if(200===t.status){clearTimeout(c);const r=Date.now()-o;return void e(Object.assign(t,{usedXBind:!0,transport:{protocol:"xbind",latency:r,peerDID:a}}))}}catch{continue}}clearTimeout(c),s(new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.TIMEOUT,"Response not available after polling",{url:t,correlationId:d,polls:g}))}catch(e){clearTimeout(c),s(e instanceof agent_call_js_1.AgentError?e:new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.NETWORK_ERROR,"xBind request failed",{url:t,error:String(e)}))}})()})}async function sendViaHTTP(t,e){const r=Date.now(),{forceXBind:n,disableXBind:o,agent:a,retry:i,...s}=e,c=await fetch(t,s),d=Date.now()-r;return Object.assign(c,{usedXBind:!1,transport:{protocol:t.startsWith("https")?"https":"http",latency:d}})}async function withRetry(t,e){const r=e?.maxAttempts??3,n=e?.initialDelay??1e3,o=e?.multiplier??2;let a,i=n;for(let e=1;e<=r;e++)try{return await t()}catch(t){if(a=t instanceof Error?t:new Error(String(t)),t instanceof Response&&t.status>=400&&t.status<500)throw t;e<r&&(await new Promise(t=>setTimeout(t,i)),i*=o)}throw a}async function xfetch(t,e={}){let r;try{r=new URL(t)}catch(e){throw new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.INVALID_PARAMS,`Invalid URL: ${t}`,{url:t,error:e})}if(!["http:","https:"].includes(r.protocol))throw new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.INVALID_PARAMS,`Unsupported protocol: ${r.protocol}`,{url:t,protocol:r.protocol});const n=e.timeout??3e4,o=new AbortController,a=setTimeout(()=>o.abort(),n);try{const r=e.signal?AbortSignal.any?.([e.signal,o.signal])??o.signal:o.signal,n={...e,signal:r};if(e.disableXBind)return await withRetry(()=>sendViaHTTP(t,n),e.retry);const a=await checkXBindSupport(t);if(e.forceXBind&&!a.supported)throw new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.NETWORK_ERROR,`xBind required but endpoint does not support it: ${t}`,{url:t,forceXBind:!0,capability:a});if(a.supported){const r=e.agent??await agent_js_1.Agent.from({identity:"ephemeral",identityTTL:36e5});return await withRetry(()=>sendViaXBind(t,a,n,r),e.retry)}return await withRetry(()=>sendViaHTTP(t,n),e.retry)}finally{clearTimeout(a)}}async function isXBindSupported(t){return(await checkXBindSupport(t)).supported}async function getXBindCapability(t){return checkXBindSupport(t)}