import{ok,err}from"./_deps/shared/index.js";export class CancellationError extends Error{reason;context;constructor(r,e,n){super(r),this.reason=e,this.context=n,this.name="CancellationError"}}export function createTimeoutSignal(r,e){const n=new AbortController,t=Date.now(),o=setTimeout(()=>{const t=e?.reason||`Operation timed out after ${r}ms`;n.abort(new CancellationError(t,"timeout",e?.context))},r);return{signal:n.signal,clear:()=>{clearTimeout(o)},remaining:()=>{const e=Date.now()-t;return Math.max(0,r-e)}}}export function combineSignals(r){const e=r.filter(r=>r&&!r.aborted);if(0===e.length){const e=r.find(r=>r?.aborted);return e||(new AbortController).signal}if(1===e.length)return e[0];if("function"==typeof AbortSignal.any)return AbortSignal.any(e);const n=new AbortController,t=[];for(const r of e){const e=()=>{n.abort(r.reason),t.forEach(r=>r())};r.addEventListener("abort",e,{once:!0}),t.push(()=>{r.removeEventListener("abort",e)})}return n.signal}export function onCancellation(r,e){r.aborted?Promise.resolve().then(()=>e()).catch(()=>{}):r.addEventListener("abort",()=>{Promise.resolve().then(()=>e()).catch(()=>{})},{once:!0})}export function throwIfAborted(r,e){if(r?.aborted){const n=r.reason instanceof Error?r.reason.message:String(r.reason||"Operation was cancelled");throw new CancellationError(n,"aborted",e)}}export async function withCancellation(r,e){if(!e)try{const e=await r;return ok(e)}catch(r){return err(new CancellationError(r instanceof Error?r.message:String(r),"promise_rejected"))}if(e.aborted){const r=e.reason instanceof Error?e.reason.message:String(e.reason||"Operation was cancelled");return err(new CancellationError(r,"aborted"))}return new Promise(n=>{const t=()=>{const r=e.reason instanceof Error?e.reason.message:String(e.reason||"Operation was cancelled");n(err(new CancellationError(r,"aborted")))};e.addEventListener("abort",t,{once:!0}),r.then(r=>{e.removeEventListener("abort",t),n(ok(r))}).catch(r=>{e.removeEventListener("abort",t),n(err(new CancellationError(r instanceof Error?r.message:String(r),"promise_rejected")))})})}export function delay(r,e){return new Promise((n,t)=>{if(e?.aborted){const r=e.reason instanceof Error?e.reason.message:String(e.reason||"Delay cancelled");return void t(new CancellationError(r,"aborted"))}const o=setTimeout(()=>{e&&e.removeEventListener("abort",a),n()},r),a=()=>{clearTimeout(o);const r=e.reason instanceof Error?e.reason.message:String(e.reason||"Delay cancelled");t(new CancellationError(r,"aborted"))};e&&e.addEventListener("abort",a,{once:!0})})}export async function withRetry(r,e){const n=e?.maxAttempts??3,t=e?.initialDelay??1e3,o=e?.multiplier??2,a=e?.signal,i=e?.shouldRetry??(()=>!0);let s,c=t;for(let e=1;e<=n;e++){if(a?.aborted){const r=a.reason instanceof Error?a.reason.message:String(a.reason||"Operation was cancelled");return err(new CancellationError(r,"aborted",{attempt:e}))}try{const e=await r();return ok(e)}catch(r){if(s=r instanceof Error?r:new Error(String(r)),e>=n||!i(r,e))break;try{await delay(c,a),c*=o}catch(r){if(r instanceof CancellationError)return err(r);throw r}}}return err(s||new Error("Operation failed after retries"))}export function createCancellationController(){const r=new AbortController;let e;return{signal:r.signal,get isCancelled(){return r.signal.aborted},get reason(){return e},cancel(n){e=n||"Operation cancelled",r.abort(new CancellationError(e,"manual"))},throwIfCancelled(e){throwIfAborted(r.signal,e)}}}export function isCancellationError(r){return r instanceof CancellationError||r instanceof Error&&"AbortError"===r.name||r instanceof Error&&"CancellationError"===r.name}