@vielzeug/courier 2.1.0 → 2.2.0

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.
Files changed (57) hide show
  1. package/README.md +1 -2
  2. package/dist/courier.cjs +3 -3
  3. package/dist/courier.cjs.map +1 -1
  4. package/dist/courier.d.ts +2 -2
  5. package/dist/courier.d.ts.map +1 -1
  6. package/dist/courier.iife.js +3 -3
  7. package/dist/courier.iife.js.map +1 -1
  8. package/dist/courier.js +3 -3
  9. package/dist/courier.js.map +1 -1
  10. package/dist/errors.cjs +1 -1
  11. package/dist/errors.cjs.map +1 -1
  12. package/dist/errors.d.ts +1 -2
  13. package/dist/errors.d.ts.map +1 -1
  14. package/dist/errors.js +1 -1
  15. package/dist/errors.js.map +1 -1
  16. package/dist/interceptors.cjs +1 -1
  17. package/dist/interceptors.cjs.map +1 -1
  18. package/dist/interceptors.d.ts +4 -4
  19. package/dist/interceptors.d.ts.map +1 -1
  20. package/dist/interceptors.js +1 -1
  21. package/dist/interceptors.js.map +1 -1
  22. package/dist/query.cjs +1 -1
  23. package/dist/query.cjs.map +1 -1
  24. package/dist/query.d.ts +3 -1
  25. package/dist/query.d.ts.map +1 -1
  26. package/dist/query.js +1 -1
  27. package/dist/query.js.map +1 -1
  28. package/dist/response.cjs +1 -1
  29. package/dist/response.cjs.map +1 -1
  30. package/dist/response.d.ts.map +1 -1
  31. package/dist/response.js +1 -1
  32. package/dist/response.js.map +1 -1
  33. package/dist/serialize.cjs +1 -1
  34. package/dist/serialize.cjs.map +1 -1
  35. package/dist/serialize.d.ts +0 -2
  36. package/dist/serialize.d.ts.map +1 -1
  37. package/dist/serialize.js +1 -1
  38. package/dist/serialize.js.map +1 -1
  39. package/dist/stream.cjs.map +1 -1
  40. package/dist/stream.d.ts +2 -9
  41. package/dist/stream.d.ts.map +1 -1
  42. package/dist/stream.js.map +1 -1
  43. package/dist/transport.cjs +1 -1
  44. package/dist/transport.cjs.map +1 -1
  45. package/dist/transport.d.ts +1 -1
  46. package/dist/transport.d.ts.map +1 -1
  47. package/dist/transport.js +1 -1
  48. package/dist/transport.js.map +1 -1
  49. package/dist/types.d.ts +9 -6
  50. package/dist/types.d.ts.map +1 -1
  51. package/package.json +7 -2
  52. package/dist/_dev.cjs +0 -2
  53. package/dist/_dev.cjs.map +0 -1
  54. package/dist/_dev.d.ts +0 -2
  55. package/dist/_dev.d.ts.map +0 -1
  56. package/dist/_dev.js +0 -2
  57. package/dist/_dev.js.map +0 -1
package/README.md CHANGED
@@ -49,9 +49,8 @@ await client.queries.fetch({
49
49
 
50
50
  const nextUser = await client.mutate({
51
51
  request: ({ signal }) => client.post<User>('/users', { body: { name: 'Alice' }, signal }),
52
+ invalidateKeys: [['users']],
52
53
  });
53
- client.queries.set(['users', nextUser.id], nextUser);
54
- client.queries.invalidate(['users']);
55
54
  ```
56
55
 
57
56
  ## Documentation
package/dist/courier.cjs CHANGED
@@ -1,6 +1,6 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},t=class t extends e{url;method;status;data;headers;constructor(e){super(e.message),this.url=e.url,this.method=e.method,this.status=e.status,this.data=e.data,this.headers=e.headers}static fromResponse(e,n,r,i){return new t({data:n,headers:e.headers,message:e.statusText||`HTTP ${e.status}`,method:r,status:e.status,url:i})}static is(e,n){return e instanceof t&&(n===void 0||e.status===n)}},n=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},r=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},i=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},a=class extends e{data;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.data=t}},o=class extends e{constructor(e){super(`[courier] ${e} disposed`)}},s=class extends e{};function c(e,t,a,o){let s=e instanceof Error?e.message:String(e),c=o?.reason;return c instanceof Error&&c.name===`TimeoutError`?new r({cause:e,message:s,method:t,url:a}):e instanceof DOMException?e.name===`TimeoutError`?new r({cause:e,message:s,method:t,url:a}):new i({cause:e,message:s,method:t,url:a}):e instanceof Error&&e.name===`AbortError`||o?.aborted?new i({cause:e,message:s,method:t,url:a}):new n({cause:e,message:s,method:t,url:a})}var l=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},u=class extends l{};function d(e,t,n){if(e===void 0)return`undefined`;if(e===null)return`null`;if(typeof e==`bigint`)return`${e}n`;if(typeof e!=`object`)return JSON.stringify(e);if(n.has(e))return`[Circular]`;if(n.add(e),e instanceof Date)return`[Date:${Number.isNaN(e.getTime())?`Invalid`:e.toISOString()}]`;if(e instanceof RegExp)return`[RegExp:${e.source}/${e.flags}]`;if(e instanceof Set)return`[Set:${[...e].map(e=>d(e,t,n)).sort().join(`,`)}]`;if(e instanceof Map)return`[Map:${[...e.entries()].map(([e,r])=>[d(e,t,n),d(r,t,n)]).sort(([e,t],[n,r])=>e===n?t.localeCompare(r):e.localeCompare(n)).map(([e,t])=>`${e}=>${t}`).join(`,`)}]`;if(Array.isArray(e))return`[${e.map(e=>d(e,t,n)).join(`,`)}]`;let r=Object.getPrototypeOf(e);if(r!==Object.prototype&&r!==null){if(t?.onClassInstance===`throw`)throw new u(`hash: unsupported type ${e.constructor?.name??`unknown`}`);return String(e)}let i=e;return`{${Object.keys(i).filter(e=>i[e]!==void 0).sort().map(e=>`${JSON.stringify(e)}:${d(i[e],t,n)}`).join(`,`)}}`}function f(e,t){return d(e,t,new Set)}function p(e,t,n,r,i){return n!==void 0&&!m(n)?{...i,body:JSON.stringify(n),headers:{"content-type":`application/json`,...t},method:e.toUpperCase(),signal:r}:{...i,...n!==void 0&&{body:n},headers:t,method:e.toUpperCase(),signal:r}}function m(e){return e instanceof FormData||e instanceof Blob||e instanceof URLSearchParams||typeof e==`string`||e instanceof ArrayBuffer||ArrayBuffer.isView(e)||typeof ReadableStream<`u`&&e instanceof ReadableStream}var h=0;function g(e=!1){return{data:void 0,error:null,isFetching:e,status:`loading`,updatedAt:void 0}}function _(e){let t=new Map,n=new Map,r=e?.signal?.aborted??!1,i=e=>{for(let t of[...n.get(f(e))??[]])t()},a=()=>{for(let e of t.values())e.controller?.abort()},s=()=>{let e=[...t.values()].map(e=>e.key);a(),t.clear();for(let t of e)i(t)};e?.signal?.addEventListener(`abort`,()=>{r=!0,s()},{once:!0});let c=e=>{let n=f(e),r=t.get(n);return r||(r={controller:void 0,definition:void 0,key:e,promise:void 0,snapshot:g()},t.set(n,r)),r},l=(t,n)=>{if(r)return Promise.reject(new o(`QueryCache`));if(!t.definition)return Promise.reject(Error(`No fetch function registered for query ${f(t.key)}.`));let a=t.definition.staleTime??e?.staleTime??h;if(!n&&t.snapshot.status===`success`&&Date.now()-t.snapshot.updatedAt<a&&!t.snapshot.isFetching)return Promise.resolve(t.snapshot.data);if(t.promise)return t.promise;let s=new AbortController;t.controller=s,t.snapshot=t.snapshot.status===`success`?{...t.snapshot,isFetching:!0}:{...g(!0)},i(t.key);let c=Promise.resolve().then(()=>t.definition?.fetch({key:t.key,signal:s.signal})).then(e=>(t.snapshot={data:e,error:null,isFetching:!1,status:`success`,updatedAt:Date.now()},t.controller=void 0,t.promise=void 0,i(t.key),e),e=>{let n=e instanceof Error?e:Error(String(e));throw t.snapshot={data:t.snapshot.status===`success`?t.snapshot.data:void 0,error:n,isFetching:!1,status:`error`,updatedAt:Date.now()},t.controller=void 0,t.promise=void 0,i(t.key),n});return t.promise=c,c};return{cancelAll:a,clear:s,fetch(e,t){let n=c(e.key);return n.definition=e,l(n,t?.force??!1)},get(e){let n=t.get(f(e));return n?.snapshot.status===`success`?n.snapshot.data:void 0},getSnapshot(e){return t.get(f(e))?.snapshot??null},invalidate(e){for(let n of t.values())e.length<=n.key.length&&e.every((e,t)=>f(e)===f(n.key[t]))&&(n.snapshot.status===`success`&&(n.snapshot={...n.snapshot,updatedAt:0}),i(n.key))},keys(){return[...t.values()].map(e=>e.key)},refetchStale(){for(let n of t.values()){if(!n.definition||n.snapshot.status!==`success`||n.snapshot.isFetching)continue;let t=n.definition.staleTime??e?.staleTime??h;Date.now()-n.snapshot.updatedAt>=t&&l(n,!0).catch(()=>{`${f(n.key)}`})}},set(e,t,n){let r=c(e);r.snapshot={data:t,error:null,isFetching:!1,status:`success`,updatedAt:n?.updatedAt??Date.now()},i(e)},subscribe(e,t){let r=f(e),i=n.get(r)??new Set;return i.add(t),n.set(r,i),()=>{i.delete(t),i.size===0&&n.delete(r)}}}}async function v(e,t=`auto`){if(t===`raw`)return e;if(e.status===204||e.status===205||e.status===304)return;if(t===`json`)return e.json();if(t===`text`)return e.text();if(t===`blob`)return e.blob();if(t===`arrayBuffer`)return e.arrayBuffer();let n=e.headers.get(`content-type`)??``;return n.includes(`application/json`)||n.includes(`+json`)?e.json():n.startsWith(`text/`)?e.text():n.startsWith(`image/`)||n.startsWith(`audio/`)||n.startsWith(`video/`)?e.blob():e.text()}function y(e,t,n){return{headers:t,init:n,url:e,withHeaders(r){let i={...t};for(let[e,t]of Object.entries(r))i[e.toLowerCase()]=t;return y(e,i,n)}}}function b(...e){let t=e.filter(e=>e!=null);if(t.length!==0)return t.length===1?t[0]:AbortSignal.any(t)}var x=3e4;function S(t){if((t<=0||!Number.isFinite(t))&&t!==1/0)throw new e(`[courier] timeout must be a positive number or Infinity`)}function C(e,t){return e===1/0?t??void 0:b(AbortSignal.timeout(e),t)}function w(e={}){let{baseUrl:t=``,fetch:n=globalThis.fetch,headers:r={},timeout:i=x}=e;S(i);let a=Object.fromEntries(Object.entries(r).map(([e,t])=>[e.toLowerCase(),t])),o=new Set,s=new AbortController,c=[],l=null,u=!1;function d(){if(l)return l;let e=e=>n(e.url,{...e.init,headers:e.headers});return l=c.length===0?e:c.reduceRight((e,t)=>n=>t(n,e),e),l}function f(e){return c.push(e),l=null,()=>{let t=c.indexOf(e);t!==-1&&(c.splice(t,1),l=null)}}function p(e){for(let[t,n]of Object.entries(e)){let e=t.toLowerCase();n===void 0?delete a[e]:a[e]=n}}function m(){return{...a}}function h(e,t){let n=e?Object.fromEntries(Object.entries(e).map(([e,t])=>[e.toLowerCase(),t])):void 0;return{...a,...n,...t}}function g(e){return o.add(e),()=>o.delete(e)}function _(e){return d()(y(e.url,e.headers,e.init))}function v(){for(let e of[...o])e.abort();o.clear()}function b(){if(!u){u=!0,s.abort();for(let e of o)e.abort();o.clear(),c.length=0,l=null}}return{baseUrl:t,cancelAll:v,dispatch:_,get disposalSignal(){return s.signal},dispose:b,get disposed(){return u},getHeaders:m,getTimeout(){return i},headers:p,mergeHeaders:h,track:g,use:f}}function T(e,t,n,r){let i=e.replace(/\/+$/,``),a=t.replace(/^\/+/,``);a=a.replace(/\{([^}]+)\}/g,(e,r)=>{let i=n?.[r];if(i==null)throw new s(`unresolved path param {${r}} in '${t}'`);return encodeURIComponent(String(i))});let o=i&&a?`${i}/${a}`:i||a;if(!r)return o;let c=new URLSearchParams;for(let[e,t]of Object.entries(r))if(t!==void 0){if(Array.isArray(t)){for(let n of t)n!==void 0&&c.append(e,n===null?``:String(n));continue}c.append(e,t===null?``:String(t))}let l=c.toString();return l?`${o}${o.includes(`?`)?`&`:`?`}${l}`:o}function E(e){let t=new AbortController,n=e(t.signal);return{next:e=>n.next(e),return:e=>(t.abort(),n.return(e)),[Symbol.asyncIterator](){return this},throw:e=>(t.abort(),n.throw(e))}}async function D(e,n,r){if(e.disposed)throw new o(`Courier`);let i=new AbortController,a=e.track(i),l=(r.method??(r.body===void 0?`GET`:`POST`)).toUpperCase(),u=C(r.timeout??1/0,b(r.signal,i.signal)),d=n;try{d=T(e.baseUrl,n,r.params,r.query);let{headers:o,...c}=p(l,e.mergeHeaders(r.headers),r.body,u,r.fetchInit??{}),f=await e.dispatch({headers:o,init:c,url:d});if(!f.ok)throw t.fromResponse(f,await f.text().catch(()=>``),l,d);if(!f.body)throw new s(`Response has no body`);return{controller:i,response:f,untrack:a}}catch(e){throw a(),e instanceof t||e instanceof s?e:c(e,l,d,u)}}function O(e){async function*t(t,n){let{controller:r,response:i,untrack:a}=await D(e,t,n),o=i.body.getReader(),s=new TextDecoder,c=``,l=`message`,u=``;try{for(;;){let e=await o.read();if(e.done)break;c+=s.decode(e.value,{stream:!0}).replace(/\r\n?/g,`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},t=class t extends e{url;method;status;data;headers;constructor(e){super(e.message),this.url=e.url,this.method=e.method,this.status=e.status,this.data=e.data,this.headers=e.headers}static fromResponse(e,n,r,i){return new t({data:n,headers:e.headers,message:e.statusText||`HTTP ${e.status}`,method:r,status:e.status,url:i})}static is(e,n){return e instanceof t&&(n===void 0||e.status===n)}},n=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},r=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},i=class extends e{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},a=class extends e{data;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.data=t}},o=class extends e{constructor(e){super(`[courier] ${e} disposed`)}},s=class extends e{};function c(e,t,a,o){let s=e instanceof Error?e.message:String(e),c=o?.reason;return c instanceof Error&&c.name===`TimeoutError`?new r({cause:e,message:s,method:t,url:a}):e instanceof DOMException?e.name===`TimeoutError`?new r({cause:e,message:s,method:t,url:a}):new i({cause:e,message:s,method:t,url:a}):e instanceof Error&&e.name===`AbortError`||o?.aborted?new i({cause:e,message:s,method:t,url:a}):new n({cause:e,message:s,method:t,url:a})}var l=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},u=class extends l{};function d(e,t,n){if(e===void 0)return`undefined`;if(e===null)return`null`;if(typeof e==`bigint`)return`${e}n`;if(typeof e!=`object`)return JSON.stringify(e);if(n.has(e))return`[Circular]`;if(n.add(e),e instanceof Date)return`[Date:${Number.isNaN(e.getTime())?`Invalid`:e.toISOString()}]`;if(e instanceof RegExp)return`[RegExp:${e.source}/${e.flags}]`;if(e instanceof Set)return`[Set:${[...e].map(e=>d(e,t,n)).sort().join(`,`)}]`;if(e instanceof Map)return`[Map:${[...e.entries()].map(([e,r])=>[d(e,t,n),d(r,t,n)]).sort(([e,t],[n,r])=>e===n?t.localeCompare(r):e.localeCompare(n)).map(([e,t])=>`${e}=>${t}`).join(`,`)}]`;if(Array.isArray(e))return`[${e.map(e=>d(e,t,n)).join(`,`)}]`;let r=Object.getPrototypeOf(e);if(r!==Object.prototype&&r!==null){if(t?.onClassInstance===`throw`)throw new u(`hash: unsupported type ${e.constructor?.name??`unknown`}`);return String(e)}let i=e;return`{${Object.keys(i).filter(e=>i[e]!==void 0).sort().map(e=>`${JSON.stringify(e)}:${d(i[e],t,n)}`).join(`,`)}}`}function f(e,t){return d(e,t,new Set)}var p=0,m=3e5;function h(e=!1){return{data:void 0,error:null,isFetching:e,status:`loading`,updatedAt:void 0}}function g(e){let t=e?.staleTime??p,n=e?.gcTime??m,r=new Map,i=new Map,a=e?.signal?.aborted??!1,s,c=e=>(i.get(e)?.size??0)>0,l=e=>{for(let t of[...i.get(f(e))??[]])t()},u=()=>{if(n===1/0||a){s&&clearTimeout(s),s=void 0;return}s&&clearTimeout(s);let e;for(let t of r.values()){if(t.snapshot.status!==`success`||t.promise||c(f(t.key)))continue;let r=t.snapshot.updatedAt+n;(e===void 0||r<e)&&(e=r)}if(e===void 0){s=void 0;return}s=setTimeout(d,Math.max(0,e-Date.now()))},d=()=>{let e=Date.now();for(let[t,i]of r)i.snapshot.status!==`success`||i.promise||c(t)||e-i.snapshot.updatedAt>=n&&r.delete(t);u()},g=()=>{for(let e of r.values())e.controller?.abort()},_=()=>{let e=[...r.values()].map(e=>e.key);g(),r.clear(),s&&=(clearTimeout(s),void 0);for(let t of e)l(t)};e?.signal?.addEventListener(`abort`,()=>{a=!0,_()},{once:!0});let v=e=>{let t=f(e),n=r.get(t);return n||(n={controller:void 0,definition:void 0,key:e,promise:void 0,snapshot:h()},r.set(t,n)),n},y=(e,n)=>{if(a)return Promise.reject(new o(`QueryCache`));if(!e.definition)return Promise.reject(Error(`No fetch function registered for query ${f(e.key)}.`));let r=e.definition.staleTime??t;if(!n&&e.snapshot.status===`success`&&Date.now()-e.snapshot.updatedAt<r&&!e.snapshot.isFetching)return Promise.resolve(e.snapshot.data);if(e.promise)return e.promise;let i=new AbortController;e.controller=i,e.snapshot=e.snapshot.status===`success`?{...e.snapshot,isFetching:!0}:{...h(!0)},l(e.key);let s=Promise.resolve().then(()=>e.definition?.fetch({key:e.key,signal:i.signal})).then(t=>(e.snapshot={data:t,error:null,isFetching:!1,status:`success`,updatedAt:Date.now()},e.controller=void 0,e.promise=void 0,l(e.key),u(),t),t=>{let n=t instanceof Error?t:Error(String(t));throw e.snapshot={data:e.snapshot.status===`success`?e.snapshot.data:void 0,error:n,isFetching:!1,status:`error`,updatedAt:Date.now()},e.controller=void 0,e.promise=void 0,l(e.key),n});return e.promise=s,s};return{cancelAll:g,clear:_,fetch(e,t){let n=v(e.key);return n.definition=e,y(n,t?.force??!1)},get(e){let t=r.get(f(e));return t?.snapshot.status===`success`?t.snapshot.data:void 0},getSnapshot(e){return r.get(f(e))?.snapshot??null},invalidate(e,t){let n=t?.refetch??!1,i=!1;for(let t of r.values())e.length<=t.key.length&&e.every((e,n)=>e===t.key[n])&&(t.snapshot.status===`success`&&(t.snapshot={...t.snapshot,updatedAt:0}),l(t.key),n&&t.definition&&!t.promise&&y(t,!0).catch(()=>{}),i=!0);i&&u()},keys(){return[...r.values()].map(e=>e.key)},set(e,t,n){let r=v(e);r.snapshot={data:t,error:null,isFetching:!1,status:`success`,updatedAt:n?.updatedAt??Date.now()},l(e),u()},subscribe(e,t){let n=f(e),r=i.get(n)??new Set;return r.add(t),i.set(n,r),()=>{r.delete(t),r.size===0&&(i.delete(n),u())}}}}async function _(e){let t=(await e.text()).trim();return t?JSON.parse(t):void 0}async function v(e,t=`auto`){if(t===`raw`)return e;if(e.status===204||e.status===205||e.status===304)return;if(t===`json`)return _(e);if(t===`text`)return e.text();if(t===`blob`)return e.blob();if(t===`arrayBuffer`)return e.arrayBuffer();let n=e.headers.get(`content-type`)??``;return n.includes(`application/json`)||n.includes(`+json`)?_(e):n.startsWith(`text/`)?e.text():n.startsWith(`image/`)||n.startsWith(`audio/`)||n.startsWith(`video/`)?e.blob():e.text()}function y(e,t,n,r,i){return n!==void 0&&!b(n)?{...i,body:JSON.stringify(n),headers:{"content-type":`application/json`,...t},method:e.toUpperCase(),signal:r}:{...i,...n!==void 0&&{body:n},headers:t,method:e.toUpperCase(),signal:r}}function b(e){return e instanceof FormData||e instanceof Blob||e instanceof URLSearchParams||typeof e==`string`||e instanceof ArrayBuffer||ArrayBuffer.isView(e)||typeof ReadableStream<`u`&&e instanceof ReadableStream}function x(e,t,n){return{headers:t,init:n,url:e,withHeaders(r){let i={...t};for(let[e,t]of Object.entries(r))i[e.toLowerCase()]=t;return x(e,i,n)}}}function S(...e){let t=e.filter(e=>e!=null);if(t.length!==0)return t.length===1?t[0]:AbortSignal.any(t)}var C=3e4;function w(t){if((t<=0||!Number.isFinite(t))&&t!==1/0)throw new e(`[courier] timeout must be a positive number or Infinity`)}function T(e,t){return e===1/0?t??void 0:S(AbortSignal.timeout(e),t)}function E(e={}){let{baseUrl:t=``,fetch:n=globalThis.fetch,headers:r={},timeout:i=C}=e;w(i);let a=Object.fromEntries(Object.entries(r).map(([e,t])=>[e.toLowerCase(),t])),o=new Set,s=new AbortController,c=[],l=null,u=!1;function d(){if(l)return l;let e=e=>n(e.url,{...e.init,headers:e.headers});return l=c.length===0?e:c.reduceRight((e,t)=>n=>t(n,e),e),l}function f(e){return c.push(e),l=null,()=>{let t=c.indexOf(e);t!==-1&&(c.splice(t,1),l=null)}}function p(e){for(let[t,n]of Object.entries(e)){let e=t.toLowerCase();n===void 0?delete a[e]:a[e]=n}}function m(){return{...a}}function h(e,t){let n=e?Object.fromEntries(Object.entries(e).map(([e,t])=>[e.toLowerCase(),t])):void 0;return{...a,...n,...t}}function g(e){return o.add(e),()=>o.delete(e)}function _(e){return d()(x(e.url,e.headers,e.init))}function v(){for(let e of[...o])e.abort();o.clear()}function y(){if(!u){u=!0,s.abort();for(let e of o)e.abort();o.clear(),c.length=0,l=null}}return{baseUrl:t,cancelAll:v,dispatch:_,get disposalSignal(){return s.signal},dispose:y,get disposed(){return u},getHeaders:m,getTimeout(){return i},mergeHeaders:h,setHeaders:p,track:g,use:f}}function D(e,t,n,r){let i=e.replace(/\/+$/,``),a=t.replace(/^\/+/,``);a=a.replace(/\{([^}]+)\}/g,(e,r)=>{let i=n?.[r];if(i==null)throw new s(`unresolved path param {${r}} in '${t}'`);return encodeURIComponent(String(i))});let o=i&&a?`${i}/${a}`:i||a;if(!r)return o;let c=new URLSearchParams;for(let[e,t]of Object.entries(r))if(t!==void 0){if(Array.isArray(t)){for(let n of t)n!==void 0&&c.append(e,n===null?``:String(n));continue}c.append(e,t===null?``:String(t))}let l=c.toString();return l?`${o}${o.includes(`?`)?`&`:`?`}${l}`:o}function O(e){let t=new AbortController,n=e(t.signal);return{next:e=>n.next(e),return:e=>(t.abort(),n.return(e)),[Symbol.asyncIterator](){return this},throw:e=>(t.abort(),n.throw(e))}}async function k(e,n,r){if(e.disposed)throw new o(`Courier`);let i=new AbortController,a=e.track(i),l=(r.method??(r.body===void 0?`GET`:`POST`)).toUpperCase(),u=T(r.timeout??1/0,S(r.signal,i.signal)),d=n;try{d=D(e.baseUrl,n,r.params,r.query);let{headers:o,...c}=y(l,e.mergeHeaders(r.headers),r.body,u,r.fetchInit??{}),f=await e.dispatch({headers:o,init:c,url:d});if(!f.ok)throw t.fromResponse(f,await f.text().catch(()=>``),l,d);if(!f.body)throw new s(`Response has no body`);return{controller:i,response:f,untrack:a}}catch(e){throw a(),e instanceof t||e instanceof s?e:c(e,l,d,u)}}function A(e){async function*t(t,n){let{controller:r,response:i,untrack:a}=await k(e,t,n),o=i.body.getReader(),s=new TextDecoder,c=``,l=`message`,u=``;try{for(;;){let e=await o.read();if(e.done)break;c+=s.decode(e.value,{stream:!0}).replace(/\r\n?/g,`
2
2
  `);let t;for(;(t=c.indexOf(`
3
3
  `))!==-1;){let e=c.slice(0,t);if(c=c.slice(t+1),e===``){if(u!==``){let e=u.endsWith(`
4
- `)?u.slice(0,-1):u;try{e=JSON.parse(e)}catch{}yield{data:e,event:l}}u=``,l=`message`;continue}if(e.startsWith(`:`))continue;let n=e.indexOf(`:`),r=n===-1?e:e.slice(0,n),i=(n===-1?``:e.slice(n+1)).replace(/^ /,``);r===`data`?u+=`${i}\n`:r===`event`&&(l=i)}}}finally{o.releaseLock(),r.abort(),a()}}async function*n(t,n){let{controller:r,response:i,untrack:a}=await D(e,t,n),o=i.body.getReader(),c=new TextDecoder,l=``;try{for(;;){let e=await o.read();if(e.done){if(n.parse===`ndjson`&&l.trim())try{yield JSON.parse(l)}catch{throw new s(`NDJSON: failed to parse line: ${l.slice(0,200)}`)}break}let t=c.decode(e.value,{stream:!0});if(n.parse!==`ndjson`){yield t;continue}l+=t;let r;for(;(r=l.indexOf(`
5
- `))!==-1;){let e=l.slice(0,r).trim();if(l=l.slice(r+1),e)try{yield JSON.parse(e)}catch{throw new s(`NDJSON: failed to parse line: ${e.slice(0,200)}`)}}}}finally{o.releaseLock(),r.abort(),a()}}return{events(e,n={}){return E(r=>t(e,{...n,headers:{accept:`text/event-stream`,"cache-control":`no-cache`,...n.headers},signal:b(n.signal,r)}))},read(e,t={}){return E(r=>n(e,{...t,signal:b(t.signal,r)}))}}}function k(e={}){let{query:n,...r}=e,i=w(r),s=_({...n,signal:i.disposalSignal}),l=s,u=O(i),d=new Set;async function f(e,n,r,o,s,l){let u=n.signal,d;try{d=await i.dispatch({headers:e,init:n,url:r})}catch(e){throw c(e,o,r,u)}if(!d.ok){let e=d.headers.get(`content-type`)?.includes(`json`)??!1,n=await d.text().catch(()=>``),i=n;if(n&&e)try{i=JSON.parse(n)}catch{}throw t.fromResponse(d,i,o,r)}let f;try{f=await v(d,s??`auto`)}catch(e){throw c(e,o,r,u)}if(l)try{return l.parse(f)}catch(e){throw new a(e,f)}return f}async function m(e,t,n={}){if(i.disposed)throw new o(`Courier`);let r=e.toUpperCase(),a;try{a=T(i.baseUrl,t,n.params,n.query)}catch(e){throw c(e,r,t)}let{body:s,fetchInit:l,headers:u,responseType:d,schema:m,signal:h,timeout:g}=n;g!==void 0&&S(g);let _=new AbortController,v=i.track(_),y=C(g??i.getTimeout(),b(h,_.signal)),{headers:x,...w}=p(r,i.mergeHeaders(u),s,y,l??{});try{return await f(x,w,a,r,d,m)}finally{v()}}return{cancelAll(){i.cancelAll(),s.cancelAll();for(let e of d)e.abort()},delete:(e,t)=>m(`DELETE`,e,t),get disposalSignal(){return i.disposalSignal},dispose(){for(let e of d)e.abort();d.clear(),l.clear(),i.dispose()},get disposed(){return i.disposed},events:u.events,get:(e,t)=>m(`GET`,e,t),getHeaders:i.getHeaders,headers:i.headers,mutate:async e=>{if(i.disposed)throw new o(`Courier`);let t=new AbortController;d.add(t);let n=b(e.signal,t.signal,i.disposalSignal)??t.signal;try{let t=await e.request({signal:n});return await e.onSuccess?.(t,l),t}finally{d.delete(t)}},patch:(e,t)=>m(`PATCH`,e,t),post:(e,t)=>m(`POST`,e,t),put:(e,t)=>m(`PUT`,e,t),queries:l,read:u.read,request:m,[Symbol.dispose](){this.dispose()},use:i.use}}function A(){return crypto.randomUUID()}function j(e){return async(t,n)=>{let r=typeof e==`function`?await e():e;return n(t.withHeaders({authorization:`Bearer ${r}`}))}}function M(e){let t=e?.header??`x-request-id`,n=e?.generate??A;return(e,r)=>r(e.withHeaders({[t]:n()}))}function N(e){let t=e?.logger??((e,t)=>{console.debug(e,t)});return async(e,n)=>{let r=performance.now(),i=(e.init.method??`GET`).toUpperCase();try{let a=await n(e),o=Math.round(performance.now()-r);return t(`${i} ${e.url} ${a.status} (${o}ms)`,{duration:o,method:i,status:a.status,url:e.url}),a}catch(n){let a=Math.round(performance.now()-r);throw t(`${i} ${e.url} ERR (${a}ms)`,{duration:a,method:i,status:0,url:e.url}),n}}}exports.CourierAbortError=i,exports.CourierDisposedError=o,exports.CourierError=e,exports.CourierHttpError=t,exports.CourierNetworkError=n,exports.CourierParseError=s,exports.CourierSchemaValidationError=a,exports.CourierTimeoutError=r,exports.createCourier=k,exports.withBearerAuth=j,exports.withLogging=N,exports.withRequestId=M;
4
+ `)?u.slice(0,-1):u;try{e=JSON.parse(e)}catch{}yield{data:e,event:l}}u=``,l=`message`;continue}if(e.startsWith(`:`))continue;let n=e.indexOf(`:`),r=n===-1?e:e.slice(0,n),i=(n===-1?``:e.slice(n+1)).replace(/^ /,``);r===`data`?u+=`${i}\n`:r===`event`&&(l=i)}}}finally{o.releaseLock(),r.abort(),a()}}async function*n(t,n){let{controller:r,response:i,untrack:a}=await k(e,t,n),o=i.body.getReader(),c=new TextDecoder,l=``;try{for(;;){let e=await o.read();if(e.done){if(n.parse===`ndjson`&&l.trim())try{yield JSON.parse(l)}catch{throw new s(`NDJSON: failed to parse line: ${l.slice(0,200)}`)}break}let t=c.decode(e.value,{stream:!0});if(n.parse!==`ndjson`){yield t;continue}l+=t;let r;for(;(r=l.indexOf(`
5
+ `))!==-1;){let e=l.slice(0,r).trim();if(l=l.slice(r+1),e)try{yield JSON.parse(e)}catch{throw new s(`NDJSON: failed to parse line: ${e.slice(0,200)}`)}}}}finally{o.releaseLock(),r.abort(),a()}}return{events(e,n={}){return O(r=>t(e,{...n,headers:{accept:`text/event-stream`,"cache-control":`no-cache`,...n.headers},signal:S(n.signal,r)}))},read(e,t={}){return O(r=>n(e,{...t,signal:S(t.signal,r)}))}}}function j(e={}){let{query:n,...r}=e,i=E(r),s=g({...n,signal:i.disposalSignal}),l=s,u=A(i),d=new Set;async function f(e,n,r,o,s,l){let u=n.signal,d;try{d=await i.dispatch({headers:e,init:n,url:r})}catch(e){throw c(e,o,r,u)}if(!d.ok){let e=d.headers.get(`content-type`)?.includes(`json`)??!1,n=await d.text().catch(()=>``),i=n;if(n&&e)try{i=JSON.parse(n)}catch{}throw t.fromResponse(d,i,o,r)}let f;try{f=await v(d,s??`auto`)}catch(e){throw c(e,o,r,u)}if(l)try{return l.parse(f)}catch(e){throw new a(e,f)}return f}async function p(e,t,n={}){if(i.disposed)throw new o(`Courier`);let r=e.toUpperCase(),a;try{a=D(i.baseUrl,t,n.params,n.query)}catch(e){throw c(e,r,t)}let{body:s,fetchInit:l,headers:u,responseType:d,schema:p,signal:m,timeout:h}=n;h!==void 0&&w(h);let g=new AbortController,_=i.track(g),v=T(h??i.getTimeout(),S(m,g.signal)),{headers:b,...x}=y(r,i.mergeHeaders(u),s,v,l??{});try{return await f(b,x,a,r,d,p)}finally{_()}}return{cancelAll(){i.cancelAll(),s.cancelAll();for(let e of d)e.abort()},delete:(e,t)=>p(`DELETE`,e,t),get disposalSignal(){return i.disposalSignal},dispose(){for(let e of d)e.abort();d.clear(),l.clear(),i.dispose()},get disposed(){return i.disposed},events:u.events,get:(e,t)=>p(`GET`,e,t),getHeaders:i.getHeaders,mutate:async e=>{if(i.disposed)throw new o(`Courier`);let t=new AbortController;d.add(t);let n=S(e.signal,t.signal,i.disposalSignal)??t.signal;try{let t=await e.request({signal:n});await e.onSuccess?.(t,l);for(let t of e.invalidateKeys??[])l.invalidate(t,{refetch:!0});return t}finally{d.delete(t)}},patch:(e,t)=>p(`PATCH`,e,t),post:(e,t)=>p(`POST`,e,t),put:(e,t)=>p(`PUT`,e,t),queries:l,read:u.read,setHeaders:i.setHeaders,[Symbol.dispose](){this.dispose()},use:i.use}}function M(){return crypto.randomUUID()}function N(e){return async(t,n)=>{let r=typeof e==`function`?await e():e;return n(t.withHeaders({authorization:`Bearer ${r}`}))}}function P(e){let t=e?.header??`x-request-id`,n=e?.generate??M;return(e,r)=>r(e.withHeaders({[t]:n()}))}function F(e){let t=e.logger;return async(e,n)=>{let r=performance.now(),i=(e.init.method??`GET`).toUpperCase();try{let a=await n(e),o=Math.round(performance.now()-r);return t(`${i} ${e.url} ${a.status} (${o}ms)`,{duration:o,method:i,status:a.status,url:e.url}),a}catch(n){let a=Math.round(performance.now()-r);throw t(`${i} ${e.url} ERR (${a}ms)`,{duration:a,method:i,status:0,url:e.url}),n}}}exports.CourierAbortError=i,exports.CourierDisposedError=o,exports.CourierError=e,exports.CourierHttpError=t,exports.CourierNetworkError=n,exports.CourierParseError=s,exports.CourierSchemaValidationError=a,exports.CourierTimeoutError=r,exports.createCourier=j,exports.withBearerAuth=N,exports.withLogging=F,exports.withRequestId=P;
6
6
  //# sourceMappingURL=courier.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"courier.cjs","names":["e","t","e"],"sources":["../src/errors.ts","../src/_dev.ts","../../arsenal/dist/errors.js","../../arsenal/dist/object/hash.js","../src/serialize.ts","../src/query.ts","../src/response.ts","../src/transport.ts","../src/url.ts","../src/stream.ts","../src/courier.ts","../../arsenal/dist/random/uuid.js","../src/interceptors.ts"],"sourcesContent":["/**\n * Base class for all courier errors.\n * Use `instanceof CourierError` to catch any courier-originated error in one branch.\n * Use `HttpError.is(e, status?)` to check for a specific HTTP status code.\n */\nexport class CourierError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is CourierError {\n return err instanceof CourierError;\n }\n}\n\n/**\n * Thrown when the server responds with a non-2xx HTTP status code.\n * Use `HttpError.is(e, status?)` to narrow to a specific status.\n */\nexport class CourierHttpError extends CourierError {\n readonly url: string;\n readonly method: string;\n readonly status: number;\n readonly data: unknown;\n readonly headers: Headers;\n\n constructor(opts: { data: unknown; headers: Headers; message: string; method: string; status: number; url: string }) {\n super(opts.message);\n this.url = opts.url;\n this.method = opts.method;\n this.status = opts.status;\n this.data = opts.data;\n this.headers = opts.headers;\n }\n\n static fromResponse(res: Response, data: unknown, method: string, url: string): CourierHttpError {\n return new CourierHttpError({\n data,\n headers: res.headers,\n message: res.statusText || `HTTP ${res.status}`,\n method,\n status: res.status,\n url,\n });\n }\n\n static is(err: unknown, status?: number): err is CourierHttpError {\n return err instanceof CourierHttpError && (status === undefined || err.status === status);\n }\n}\n\n/**\n * Thrown when a fetch fails due to a network-level error (DNS, TCP, CORS, etc.)\n * with no HTTP response. Distinct from `HttpError` so callers never need to check\n * for a missing `status` field.\n */\nexport class CourierNetworkError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a request is aborted via `AbortSignal.timeout()` or a caller-supplied\n * timeout option. Distinct from `AbortError` so callers can show retry UI on timeouts\n * without checking any `kind` discriminant.\n */\nexport class CourierTimeoutError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a request is cancelled via a caller-supplied `AbortSignal` or\n * `cancelAll()` / `dispose()`. Safe to ignore in most UI handlers.\n */\nexport class CourierAbortError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a response body fails schema validation (via the `schema` option).\n * Distinct from the HTTP error classes so callers can separately handle network failures\n * vs. data contract violations without inspecting the error shape.\n */\nexport class CourierSchemaValidationError extends CourierError {\n /** The raw (pre-validation) response body that failed parsing. */\n readonly data: unknown;\n\n constructor(cause: unknown, data: unknown) {\n super(cause instanceof Error ? cause.message : String(cause), { cause });\n this.data = data;\n }\n}\n\n/** Thrown when a method is called on a disposed client instance. */\nexport class CourierDisposedError extends CourierError {\n constructor(clientName: string) {\n super(`[courier] ${clientName} disposed`);\n }\n}\n\n/** Thrown when a response body cannot be read or parsed. */\nexport class CourierParseError extends CourierError {}\n\n/**\n * Classify an error thrown by `fetch` or an abort signal into the appropriate\n * courier error class. Signal reason is checked first so a timed-out signal\n * always produces `TimeoutError` even when `fetch` throws a generic Error.\n *\n * We check `.name` rather than `instanceof DOMException` because `AbortSignal.timeout()`\n * sets reason to the *native* Node.js DOMException which may differ from the environment's\n * global DOMException (e.g. jsdom), causing `instanceof` checks to fail cross-realm.\n */\nexport function classifyRequestError(\n cause: unknown,\n method: string,\n url: string,\n signal?: AbortSignal,\n): CourierNetworkError | CourierTimeoutError | CourierAbortError {\n const message = cause instanceof Error ? cause.message : String(cause);\n\n // Signal reason is authoritative — a timed-out signal carries a TimeoutError reason\n // regardless of what error `fetch` actually threw.\n const reason = signal?.reason;\n\n if (reason instanceof Error && reason.name === 'TimeoutError') {\n return new CourierTimeoutError({ cause, message, method, url });\n }\n\n if (cause instanceof DOMException) {\n if (cause.name === 'TimeoutError') return new CourierTimeoutError({ cause, message, method, url });\n\n return new CourierAbortError({ cause, message, method, url });\n }\n\n if ((cause instanceof Error && cause.name === 'AbortError') || signal?.aborted) {\n return new CourierAbortError({ cause, message, method, url });\n }\n\n return new CourierNetworkError({ cause, message, method, url });\n}\n","const isDev = !(globalThis as { __COURIER_PROD__?: boolean }).__COURIER_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/courier] ${msg}`);\n}\n","//#region src/errors.ts\nvar e = class e extends Error {\n\tconstructor(e, t) {\n\t\tsuper(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);\n\t}\n\tstatic is(t) {\n\t\treturn t instanceof e;\n\t}\n}, t = class extends e {};\n//#endregion\nexport { e as ArsenalError, t as ArsenalSerializationError };\n\n//# sourceMappingURL=errors.js.map","import { ArsenalSerializationError as e } from \"../errors.js\";\n//#region src/object/hash.ts\nfunction t(n, r, i) {\n\tif (n === void 0) return \"undefined\";\n\tif (n === null) return \"null\";\n\tif (typeof n == \"bigint\") return `${n}n`;\n\tif (typeof n != \"object\") return JSON.stringify(n);\n\tif (i.has(n)) return \"[Circular]\";\n\tif (i.add(n), n instanceof Date) return `[Date:${Number.isNaN(n.getTime()) ? \"Invalid\" : n.toISOString()}]`;\n\tif (n instanceof RegExp) return `[RegExp:${n.source}/${n.flags}]`;\n\tif (n instanceof Set) return `[Set:${[...n].map((e) => t(e, r, i)).sort().join(\",\")}]`;\n\tif (n instanceof Map) return `[Map:${[...n.entries()].map(([e, n]) => [t(e, r, i), t(n, r, i)]).sort(([e, t], [n, r]) => e === n ? t.localeCompare(r) : e.localeCompare(n)).map(([e, t]) => `${e}=>${t}`).join(\",\")}]`;\n\tif (Array.isArray(n)) return `[${n.map((e) => t(e, r, i)).join(\",\")}]`;\n\tlet a = Object.getPrototypeOf(n);\n\tif (a !== Object.prototype && a !== null) {\n\t\tif (r?.onClassInstance === \"throw\") throw new e(`hash: unsupported type ${n.constructor?.name ?? \"unknown\"}`);\n\t\treturn String(n);\n\t}\n\tlet o = n;\n\treturn `{${Object.keys(o).filter((e) => o[e] !== void 0).sort().map((e) => `${JSON.stringify(e)}:${t(o[e], r, i)}`).join(\",\")}}`;\n}\nfunction n(e, n) {\n\treturn t(e, n, /* @__PURE__ */ new Set());\n}\n//#endregion\nexport { n as hash };\n\n//# sourceMappingURL=hash.js.map","import { hash } from '@vielzeug/arsenal/object';\n\nexport { hash };\n\n/**\n * Build a `RequestInit` object from the request components, handling body serialisation.\n * Plain objects/arrays are JSON-serialised and `content-type: application/json` is added.\n * BodyInit values (FormData, Blob, etc.) are forwarded as-is.\n */\nexport function buildRequestInit(\n method: string,\n headers: Record<string, string>,\n body: unknown,\n signal: AbortSignal | undefined,\n rest: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'>,\n): RequestInit {\n if (body !== undefined && !isBodyInit(body)) {\n return {\n ...rest,\n body: JSON.stringify(body),\n headers: { 'content-type': 'application/json', ...headers },\n method: method.toUpperCase(),\n signal,\n };\n }\n\n return {\n ...rest,\n ...(body !== undefined && { body: body as BodyInit }),\n headers,\n method: method.toUpperCase(),\n signal,\n };\n}\n\nexport function isBodyInit(value: unknown): value is BodyInit {\n return (\n value instanceof FormData ||\n value instanceof Blob ||\n value instanceof URLSearchParams ||\n typeof value === 'string' ||\n value instanceof ArrayBuffer ||\n ArrayBuffer.isView(value) ||\n (typeof ReadableStream !== 'undefined' && value instanceof ReadableStream)\n );\n}\n","import { warn } from './_dev';\nimport { CourierDisposedError } from './errors';\nimport { hash } from './serialize';\nimport type { AsyncState, QueryCache, QueryContext, QueryDefinition, QueryKey, Unsubscribe } from './types';\n\nconst DEFAULT_STALE_TIME = 0;\n\ntype Entry = {\n controller: AbortController | undefined;\n definition: QueryDefinition<unknown> | undefined;\n key: QueryKey;\n promise: Promise<unknown> | undefined;\n snapshot: AsyncState<unknown>;\n};\n\ntype CancellableQueryCache = QueryCache & {\n cancelAll(): void;\n};\n\nfunction loading<T>(isFetching = false): AsyncState<T> {\n return { data: undefined, error: null, isFetching, status: 'loading', updatedAt: undefined };\n}\n\n/** Transport-agnostic cache. Queries are identified by explicit keys and fetch definitions. */\nexport function createQueryCache(options?: { signal?: AbortSignal; staleTime?: number }): CancellableQueryCache {\n const entries = new Map<string, Entry>();\n const listeners = new Map<string, Set<Unsubscribe>>();\n let disposed = options?.signal?.aborted ?? false;\n\n const notify = (key: QueryKey): void => {\n for (const listener of [...(listeners.get(hash(key)) ?? [])]) listener();\n };\n\n const cancelAll = (): void => {\n for (const entry of entries.values()) entry.controller?.abort();\n };\n\n const clear = (): void => {\n const keys = [...entries.values()].map((entry) => entry.key);\n\n cancelAll();\n entries.clear();\n\n for (const key of keys) notify(key);\n };\n\n options?.signal?.addEventListener(\n 'abort',\n () => {\n disposed = true;\n clear();\n },\n { once: true },\n );\n\n const entryFor = (key: QueryKey): Entry => {\n const id = hash(key);\n let entry = entries.get(id);\n\n if (!entry) {\n entry = {\n controller: undefined,\n definition: undefined,\n key,\n promise: undefined,\n snapshot: loading(),\n };\n entries.set(id, entry);\n }\n\n return entry;\n };\n\n const fetchEntry = <T>(entry: Entry, force: boolean): Promise<T> => {\n if (disposed) return Promise.reject(new CourierDisposedError('QueryCache'));\n\n if (!entry.definition)\n return Promise.reject(new Error(`No fetch function registered for query ${hash(entry.key)}.`));\n\n const staleTime = entry.definition.staleTime ?? options?.staleTime ?? DEFAULT_STALE_TIME;\n\n if (\n !force &&\n entry.snapshot.status === 'success' &&\n Date.now() - entry.snapshot.updatedAt < staleTime &&\n !entry.snapshot.isFetching\n ) {\n return Promise.resolve(entry.snapshot.data as T);\n }\n\n if (entry.promise) return entry.promise as Promise<T>;\n\n const controller = new AbortController();\n\n entry.controller = controller;\n entry.snapshot =\n entry.snapshot.status === 'success' ? { ...entry.snapshot, isFetching: true } : { ...loading<unknown>(true) };\n notify(entry.key);\n\n const promise = Promise.resolve()\n .then(() => entry.definition?.fetch({ key: entry.key, signal: controller.signal } as QueryContext))\n .then(\n (data) => {\n entry.snapshot = { data, error: null, isFetching: false, status: 'success', updatedAt: Date.now() };\n entry.controller = undefined;\n entry.promise = undefined;\n notify(entry.key);\n\n return data;\n },\n (cause: unknown) => {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n\n entry.snapshot = {\n data: entry.snapshot.status === 'success' ? entry.snapshot.data : undefined,\n error,\n isFetching: false,\n status: 'error',\n updatedAt: Date.now(),\n };\n entry.controller = undefined;\n entry.promise = undefined;\n notify(entry.key);\n\n throw error;\n },\n );\n\n entry.promise = promise;\n\n return promise as Promise<T>;\n };\n\n return {\n cancelAll,\n clear,\n fetch<T>(definition: QueryDefinition<T>, fetchOptions?: { force?: boolean }): Promise<T> {\n const entry = entryFor(definition.key);\n\n entry.definition = definition as QueryDefinition<unknown>;\n\n return fetchEntry<T>(entry, fetchOptions?.force ?? false);\n },\n get<T>(key: QueryKey): T | undefined {\n const entry = entries.get(hash(key));\n\n return entry?.snapshot.status === 'success' ? (entry.snapshot.data as T) : undefined;\n },\n getSnapshot<T>(key: QueryKey): AsyncState<T> | null {\n return (entries.get(hash(key))?.snapshot as AsyncState<T> | undefined) ?? null;\n },\n invalidate(prefix: readonly unknown[]): void {\n for (const entry of entries.values()) {\n const matches =\n prefix.length <= entry.key.length && prefix.every((atom, index) => hash(atom) === hash(entry.key[index]));\n\n if (matches) {\n if (entry.snapshot.status === 'success') entry.snapshot = { ...entry.snapshot, updatedAt: 0 };\n\n notify(entry.key);\n }\n }\n },\n keys(): QueryKey[] {\n return [...entries.values()].map((entry) => entry.key);\n },\n refetchStale(): void {\n for (const entry of entries.values()) {\n if (!entry.definition || entry.snapshot.status !== 'success' || entry.snapshot.isFetching) continue;\n\n const staleTime = entry.definition.staleTime ?? options?.staleTime ?? DEFAULT_STALE_TIME;\n\n if (Date.now() - entry.snapshot.updatedAt >= staleTime) {\n void fetchEntry(entry, true).catch(() => {\n warn(`Failed to refetch stale query ${hash(entry.key)}.`);\n });\n }\n }\n },\n set<T>(key: QueryKey, data: T, setOptions?: { updatedAt?: number }): void {\n const entry = entryFor(key);\n\n entry.snapshot = {\n data,\n error: null,\n isFetching: false,\n status: 'success',\n updatedAt: setOptions?.updatedAt ?? Date.now(),\n };\n notify(key);\n },\n subscribe(key: QueryKey, listener: () => void): Unsubscribe {\n const id = hash(key);\n const keyListeners = listeners.get(id) ?? new Set<Unsubscribe>();\n\n keyListeners.add(listener);\n listeners.set(id, keyListeners);\n\n return () => {\n keyListeners.delete(listener);\n\n if (keyListeners.size === 0) listeners.delete(id);\n };\n },\n };\n}\n","/** Response parsing strategy. 'raw' returns the Response object directly. */\nexport type ResponseType = 'auto' | 'json' | 'text' | 'blob' | 'arrayBuffer' | 'raw';\n\nexport async function parseResponse(res: Response, responseType: ResponseType = 'auto'): Promise<unknown> {\n if (responseType === 'raw') return res;\n\n if (res.status === 204 || res.status === 205 || res.status === 304) return;\n\n if (responseType === 'json') return res.json();\n\n if (responseType === 'text') return res.text();\n\n if (responseType === 'blob') return res.blob();\n\n if (responseType === 'arrayBuffer') return res.arrayBuffer();\n\n const contentType = res.headers.get('content-type') ?? '';\n\n if (contentType.includes('application/json') || contentType.includes('+json')) return res.json();\n\n if (contentType.startsWith('text/')) return res.text();\n\n if (contentType.startsWith('image/') || contentType.startsWith('audio/') || contentType.startsWith('video/')) {\n return res.blob();\n }\n\n // Unknown content-type — fall back to text, which is always safe to read and debug.\n return res.text();\n}\n","import { CourierError } from './errors';\n\n/**\n * Immutable request context passed through the interceptor pipeline.\n *\n * **Never mutate `init` or `headers` directly.** Use `ctx.withHeaders(updates)` to\n * produce a new context with merged headers — this is the safe, idiomatic pattern\n * for interceptors that need to add or override headers.\n *\n * @example\n * ```ts\n * // Correct — returns a new context\n * return next(ctx.withHeaders({ authorization: `Bearer ${token}` }));\n *\n * // Wrong — mutates shared state, risks stomping other interceptors\n * ctx.init.headers = { ...ctx.init.headers, authorization: `Bearer ${token}` };\n * ```\n */\nexport type FetchContext = {\n readonly headers: Readonly<Record<string, string>>;\n readonly init: Readonly<Omit<RequestInit, 'headers'>>;\n readonly url: string;\n /** Returns a new `FetchContext` with the given header overrides merged in (lowercase keys). */\n withHeaders(updates: Record<string, string>): FetchContext;\n};\n\nfunction makeFetchContext(\n url: string,\n headers: Record<string, string>,\n init: Omit<RequestInit, 'headers'>,\n): FetchContext {\n const ctx: FetchContext = {\n headers,\n init,\n url,\n withHeaders(updates: Record<string, string>): FetchContext {\n const merged = { ...headers };\n\n for (const [k, v] of Object.entries(updates)) merged[k.toLowerCase()] = v;\n\n return makeFetchContext(url, merged, init);\n },\n };\n\n return ctx;\n}\n\nexport function anySignal(...signals: ReadonlyArray<AbortSignal | null | undefined>): AbortSignal | undefined {\n const active = signals.filter((s): s is AbortSignal => s != null);\n\n if (active.length === 0) return undefined;\n\n if (active.length === 1) return active[0];\n\n return AbortSignal.any(active);\n}\nexport type Interceptor = (ctx: FetchContext, next: (ctx: FetchContext) => Promise<Response>) => Promise<Response>;\n\nexport type TransportOptions = {\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n headers?: Record<string, string>;\n timeout?: number;\n};\n\nexport const DEFAULT_TIMEOUT = 30_000;\n\nexport function validateTimeout(timeoutMs: number): void {\n if ((timeoutMs <= 0 || !Number.isFinite(timeoutMs)) && timeoutMs !== Number.POSITIVE_INFINITY) {\n throw new CourierError('[courier] timeout must be a positive number or Infinity');\n }\n}\n\nexport function buildTimeoutSignal(timeoutMs: number, external?: AbortSignal | null): AbortSignal | undefined {\n if (timeoutMs === Number.POSITIVE_INFINITY) {\n return external ?? undefined;\n }\n\n return anySignal(AbortSignal.timeout(timeoutMs), external);\n}\n\n/**\n * Shared transport core: interceptor pipeline, header management, AbortController lifecycle.\n * HTTP requests and streams build on this to avoid duplicating infrastructure.\n */\nexport function createTransportCore(opts: TransportOptions = {}) {\n const {\n baseUrl = '',\n fetch: fetchFn = globalThis.fetch,\n headers: initialHeaders = {},\n timeout = DEFAULT_TIMEOUT,\n } = opts;\n\n validateTimeout(timeout);\n\n const globalHeaders: Record<string, string> = Object.fromEntries(\n Object.entries(initialHeaders).map(([k, v]) => [k.toLowerCase(), v]),\n );\n const activeControllers = new Set<AbortController>();\n const disposeController = new AbortController();\n const interceptors: Interceptor[] = [];\n let cachedPipeline: ((ctx: FetchContext) => Promise<Response>) | null = null;\n let disposed = false;\n\n function getPipeline(): (ctx: FetchContext) => Promise<Response> {\n if (cachedPipeline) return cachedPipeline;\n\n const base: (ctx: FetchContext) => Promise<Response> = (ctx) =>\n fetchFn(ctx.url, { ...ctx.init, headers: ctx.headers });\n\n cachedPipeline =\n interceptors.length === 0\n ? base\n : interceptors.reduceRight<(ctx: FetchContext) => Promise<Response>>(\n (next, interceptor) => (ctx) => interceptor(ctx, next),\n base,\n );\n\n return cachedPipeline;\n }\n\n function use(interceptor: Interceptor): () => void {\n interceptors.push(interceptor);\n cachedPipeline = null;\n\n return () => {\n const i = interceptors.indexOf(interceptor);\n\n if (i !== -1) {\n interceptors.splice(i, 1);\n cachedPipeline = null;\n }\n };\n }\n\n function headers(updates: Record<string, string | undefined>): void {\n for (const [key, value] of Object.entries(updates)) {\n const k = key.toLowerCase();\n\n if (value === undefined) delete globalHeaders[k];\n else globalHeaders[k] = value;\n }\n }\n\n /** Returns a read-only snapshot of the current global headers. */\n function getHeaders(): Readonly<Record<string, string>> {\n return { ...globalHeaders };\n }\n\n /**\n * Merge global headers with optional per-request and extra headers.\n * Per-request keys are normalised to lowercase.\n */\n function mergeHeaders(perRequest?: Record<string, string>, extra?: Record<string, string>): Record<string, string> {\n const normalized = perRequest\n ? Object.fromEntries(Object.entries(perRequest).map(([k, v]) => [k.toLowerCase(), v]))\n : undefined;\n\n return { ...globalHeaders, ...normalized, ...extra };\n }\n\n /** Register an AbortController for lifecycle tracking (cancelAll / dispose). Returns an untrack fn. */\n function track(ac: AbortController): () => void {\n activeControllers.add(ac);\n\n return () => activeControllers.delete(ac);\n }\n\n /**\n * Dispatch a request through the interceptor pipeline.\n * Accepts a plain `{ url, headers, init }` object and promotes it to a\n * full `FetchContext` with `withHeaders()` before entering the pipeline.\n */\n function dispatch(raw: {\n headers: Record<string, string>;\n init: Omit<RequestInit, 'headers'>;\n url: string;\n }): Promise<Response> {\n return getPipeline()(makeFetchContext(raw.url, raw.headers, raw.init));\n }\n\n function cancelAll(): void {\n for (const ac of [...activeControllers]) ac.abort();\n activeControllers.clear();\n }\n\n function dispose(): void {\n if (disposed) return;\n\n disposed = true;\n disposeController.abort();\n\n for (const ac of activeControllers) ac.abort();\n\n activeControllers.clear();\n interceptors.length = 0;\n cachedPipeline = null;\n }\n\n return {\n baseUrl,\n cancelAll,\n dispatch,\n get disposalSignal() {\n return disposeController.signal;\n },\n dispose,\n get disposed() {\n return disposed;\n },\n getHeaders,\n /** Returns the configured request timeout in ms. */\n getTimeout(): number {\n return timeout;\n },\n headers,\n mergeHeaders,\n track,\n use,\n };\n}\n\nexport type TransportCore = ReturnType<typeof createTransportCore>;\n","import { CourierParseError } from './errors';\nimport type { ResponseType } from './response';\n\ntype QueryScalar = string | number | boolean | null;\n\nexport type ParamValue = QueryScalar | readonly QueryScalar[] | undefined;\nexport type Params = Record<string, ParamValue>;\n\n// Type-safe path params: extracts {param} placeholders from a path string\ntype ExtractPathParams<P extends string> = P extends `${string}{${infer K}}${infer R}`\n ? K | ExtractPathParams<R>\n : never;\n\nexport type PathConfig<P extends string> = [ExtractPathParams<P>] extends [never]\n ? { params?: never }\n : { params: Record<ExtractPathParams<P>, string | number | boolean> };\n\nexport type CourierRequestConfig<P extends string = string, T = unknown> = PathConfig<P> & {\n /** Request body. Plain objects → JSON. BodyInit values passed as-is. */\n body?: unknown;\n /** Query string parameters. */\n query?: Params;\n /** Response parsing strategy. */\n responseType?: ResponseType;\n /**\n * Optional schema for response validation. Any object with a `parse(data)` method\n * works — e.g. a `@vielzeug/spell` schema or a plain validator function wrapper.\n * Called after the response body is parsed; throws if validation fails.\n * The schema's return type must be assignable to `T`.\n */\n schema?: { parse(data: unknown): T };\n /** Request timeout in ms. Overrides client default. */\n timeout?: number;\n};\n\nexport type HttpRequestConfig<P extends string = string, T = unknown> = CourierRequestConfig<P, T> & {\n /** Raw fetch options for advanced use (credentials, cache, mode, referrer, etc.). */\n fetchInit?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'>;\n /** Per-request headers merged with (and overriding) global client headers. */\n headers?: Record<string, string>;\n /** External abort signal merged with internal cancellation. */\n signal?: AbortSignal;\n};\n\nexport function buildUrl(base: string, path: string, params?: Params, query?: Params): string {\n const baseClean = base.replace(/\\/+$/, '');\n let pathClean = path.replace(/^\\/+/, '');\n\n pathClean = pathClean.replace(/\\{([^}]+)\\}/g, (_, key: string) => {\n const val = params?.[key];\n\n if (val === undefined || val === null) throw new CourierParseError(`unresolved path param {${key}} in '${path}'`);\n\n return encodeURIComponent(String(val));\n });\n\n const url = baseClean && pathClean ? `${baseClean}/${pathClean}` : baseClean || pathClean;\n\n if (!query) return url;\n\n const qs = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n if (entry !== undefined) {\n qs.append(key, entry === null ? '' : String(entry));\n }\n }\n\n continue;\n }\n\n qs.append(key, value === null ? '' : String(value));\n }\n\n const queryString = qs.toString();\n\n return queryString ? `${url}${url.includes('?') ? '&' : '?'}${queryString}` : url;\n}\n","import { CourierDisposedError, CourierHttpError, CourierParseError, classifyRequestError } from './errors';\nimport { buildRequestInit } from './serialize';\nimport { anySignal, buildTimeoutSignal, type TransportCore } from './transport';\nimport type { Params } from './url';\nimport { buildUrl } from './url';\n\nexport type StreamOptions<P extends string = string> = {\n body?: unknown;\n fetchInit?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'>;\n headers?: Record<string, string>;\n method?: string;\n params?: P extends string ? Record<string, string | number | boolean> : never;\n query?: Params;\n signal?: AbortSignal;\n timeout?: number;\n};\n\nexport type StreamEvent<T = unknown> = { readonly data: T; readonly event: string };\n\nfunction abortable<T>(create: (signal: AbortSignal) => AsyncGenerator<T>): AsyncIterableIterator<T> {\n const controller = new AbortController();\n const iterator = create(controller.signal);\n\n return {\n next: (value?: undefined) => iterator.next(value),\n return: (value?: T) => {\n controller.abort();\n\n return iterator.return(value as T);\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n throw: (error?: unknown) => {\n controller.abort();\n\n return iterator.throw(error);\n },\n };\n}\n\nasync function open(\n transport: TransportCore,\n url: string,\n config: StreamOptions,\n): Promise<{ controller: AbortController; response: Response; untrack: () => void }> {\n if (transport.disposed) throw new CourierDisposedError('Courier');\n\n const controller = new AbortController();\n const untrack = transport.track(controller);\n const method = (config.method ?? (config.body === undefined ? 'GET' : 'POST')).toUpperCase();\n const signal = buildTimeoutSignal(\n config.timeout ?? Number.POSITIVE_INFINITY,\n anySignal(config.signal, controller.signal),\n );\n let fullUrl = url;\n\n try {\n fullUrl = buildUrl(transport.baseUrl, url, config.params as Params | undefined, config.query);\n\n const headers = transport.mergeHeaders(config.headers);\n const { headers: requestHeaders, ...init } = buildRequestInit(\n method,\n headers,\n config.body,\n signal,\n config.fetchInit ?? {},\n );\n const response = await transport.dispatch({\n headers: requestHeaders as Record<string, string>,\n init,\n url: fullUrl,\n });\n\n if (!response.ok)\n throw CourierHttpError.fromResponse(response, await response.text().catch(() => ''), method, fullUrl);\n\n if (!response.body) throw new CourierParseError('Response has no body');\n\n return { controller, response, untrack };\n } catch (error) {\n untrack();\n\n if (error instanceof CourierHttpError || error instanceof CourierParseError) throw error;\n\n throw classifyRequestError(error, method, fullUrl, signal);\n }\n}\n\n/** Platform-shaped streaming primitives: async iteration owns cancellation and backpressure. */\nexport function createStreams(transport: TransportCore) {\n async function* events<T = unknown, P extends string = string>(\n url: P,\n config: StreamOptions<P>,\n ): AsyncGenerator<StreamEvent<T>> {\n const { controller, response, untrack } = await open(transport, url, config);\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let event = 'message';\n let data = '';\n\n try {\n while (true) {\n const chunk = await reader.read();\n\n if (chunk.done) break;\n\n buffer += decoder.decode(chunk.value, { stream: true }).replace(/\\r\\n?/g, '\\n');\n\n let newline: number;\n\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline);\n\n buffer = buffer.slice(newline + 1);\n\n if (line === '') {\n if (data !== '') {\n let parsed: unknown = data.endsWith('\\n') ? data.slice(0, -1) : data;\n\n try {\n parsed = JSON.parse(parsed as string);\n } catch {\n // SSE text payloads are valid raw values.\n }\n\n yield { data: parsed as T, event };\n }\n\n data = '';\n event = 'message';\n continue;\n }\n\n if (line.startsWith(':')) continue;\n\n const separator = line.indexOf(':');\n const field = separator === -1 ? line : line.slice(0, separator);\n const value = (separator === -1 ? '' : line.slice(separator + 1)).replace(/^ /, '');\n\n if (field === 'data') data += `${value}\\n`;\n else if (field === 'event') event = value;\n }\n }\n } finally {\n reader.releaseLock();\n controller.abort();\n untrack();\n }\n }\n\n async function* read<T = string, P extends string = string>(\n url: P,\n config: StreamOptions<P> & { parse?: 'ndjson' | 'text' },\n ): AsyncGenerator<T> {\n const { controller, response, untrack } = await open(transport, url, config);\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const chunk = await reader.read();\n\n if (chunk.done) {\n if (config.parse === 'ndjson' && buffer.trim()) {\n try {\n yield JSON.parse(buffer) as T;\n } catch {\n throw new CourierParseError(`NDJSON: failed to parse line: ${buffer.slice(0, 200)}`);\n }\n }\n\n break;\n }\n\n const text = decoder.decode(chunk.value, { stream: true });\n\n if (config.parse !== 'ndjson') {\n yield text as T;\n continue;\n }\n\n buffer += text;\n\n let newline: number;\n\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline).trim();\n\n buffer = buffer.slice(newline + 1);\n\n if (!line) continue;\n\n try {\n yield JSON.parse(line) as T;\n } catch {\n throw new CourierParseError(`NDJSON: failed to parse line: ${line.slice(0, 200)}`);\n }\n }\n }\n } finally {\n reader.releaseLock();\n controller.abort();\n untrack();\n }\n }\n\n return {\n events<T = unknown, P extends string = string>(\n url: P,\n config: StreamOptions<P> = {},\n ): AsyncIterableIterator<StreamEvent<T>> {\n return abortable((signal) =>\n events<T, P>(url, {\n ...config,\n headers: { accept: 'text/event-stream', 'cache-control': 'no-cache', ...config.headers },\n signal: anySignal(config.signal, signal),\n }),\n );\n },\n read<T = string, P extends string = string>(\n url: P,\n config: StreamOptions<P> & { parse?: 'ndjson' | 'text' } = {},\n ): AsyncIterableIterator<T> {\n return abortable((signal) => read<T, P>(url, { ...config, signal: anySignal(config.signal, signal) }));\n },\n };\n}\n","import { CourierDisposedError, CourierHttpError, CourierSchemaValidationError, classifyRequestError } from './errors';\nimport { createQueryCache } from './query';\nimport { parseResponse } from './response';\nimport { buildRequestInit } from './serialize';\nimport { createStreams } from './stream';\nimport {\n anySignal,\n buildTimeoutSignal,\n createTransportCore,\n type TransportOptions,\n validateTimeout,\n} from './transport';\nimport type { MutationOptions, QueryCache } from './types';\nimport type { HttpRequestConfig, Params } from './url';\nimport { buildUrl } from './url';\n\nexport type CourierOptions = TransportOptions & {\n query?: { staleTime?: number };\n};\n\nexport type Courier = ReturnType<typeof createCourier>;\n\n/** One application client owns transport, queries, mutations, and streams. */\nexport function createCourier(options: CourierOptions = {}) {\n const { query: queryOptions, ...transportOptions } = options;\n const transport = createTransportCore(transportOptions);\n const queryCache = createQueryCache({ ...queryOptions, signal: transport.disposalSignal });\n const queries: QueryCache = queryCache;\n const streams = createStreams(transport);\n const mutations = new Set<AbortController>();\n\n async function execute<T>(\n headers: Record<string, string>,\n init: Omit<RequestInit, 'headers'>,\n full: string,\n m: string,\n responseType: HttpRequestConfig['responseType'],\n schema?: { parse(data: unknown): T },\n ): Promise<T> {\n const signal = init.signal as AbortSignal | undefined;\n let res: Response;\n\n try {\n res = await transport.dispatch({ headers, init, url: full });\n } catch (err) {\n throw classifyRequestError(err, m, full, signal);\n }\n\n if (!res.ok) {\n // Error bodies are read once as text, then JSON-parsed if the content-type\n // says so — a binary success config (`responseType: 'blob'`) must not trap\n // the server's error message in an unreadable wrapper, and a failed\n // parseResponse-then-fallback double-read loses the body entirely.\n const isJson = res.headers.get('content-type')?.includes('json') ?? false;\n const text = await res.text().catch(() => '');\n let body: unknown = text;\n\n if (text && isJson) {\n try {\n body = JSON.parse(text);\n } catch {\n // Malformed JSON error body — keep the raw text, not ''.\n }\n }\n\n throw CourierHttpError.fromResponse(res, body, m, full);\n }\n\n let raw: unknown;\n\n try {\n raw = await parseResponse(res, responseType ?? 'auto');\n } catch (err) {\n throw classifyRequestError(err, m, full, signal);\n }\n\n if (schema) {\n try {\n return schema.parse(raw);\n } catch (err) {\n throw new CourierSchemaValidationError(err, raw);\n }\n }\n\n return raw as T;\n }\n\n async function request<T, P extends string = string>(\n method: string,\n url: P,\n config: HttpRequestConfig<P> = {} as HttpRequestConfig<P>,\n ) {\n if (transport.disposed) throw new CourierDisposedError('Courier');\n\n const m = method.toUpperCase();\n\n let full: string;\n\n try {\n full = buildUrl(transport.baseUrl, url, config.params as Params | undefined, config.query);\n } catch (err) {\n throw classifyRequestError(err, m, url);\n }\n\n const {\n body,\n fetchInit,\n headers,\n responseType,\n schema,\n signal: extSignal,\n timeout: cfgTimeout,\n } = config as HttpRequestConfig;\n\n if (cfgTimeout !== undefined) validateTimeout(cfgTimeout);\n\n const requestAc = new AbortController();\n const untrack = transport.track(requestAc);\n const signal = buildTimeoutSignal(cfgTimeout ?? transport.getTimeout(), anySignal(extSignal, requestAc.signal));\n const { headers: initHeaders, ...restInit } = buildRequestInit(\n m,\n transport.mergeHeaders(headers),\n body,\n signal,\n fetchInit ?? {},\n );\n\n try {\n return await execute<T>(\n initHeaders as Record<string, string>,\n restInit,\n full,\n m,\n responseType,\n schema as { parse(data: unknown): T } | undefined,\n );\n } finally {\n untrack();\n }\n }\n\n const mutate = async <T>(options: MutationOptions<T>): Promise<T> => {\n if (transport.disposed) throw new CourierDisposedError('Courier');\n\n const controller = new AbortController();\n\n mutations.add(controller);\n\n const signal = anySignal(options.signal, controller.signal, transport.disposalSignal) ?? controller.signal;\n\n try {\n const data = await options.request({ signal });\n\n await options.onSuccess?.(data, queries);\n\n return data;\n } finally {\n mutations.delete(controller);\n }\n };\n\n return {\n cancelAll() {\n transport.cancelAll();\n queryCache.cancelAll();\n for (const controller of mutations) controller.abort();\n },\n delete: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('DELETE', url, cfg),\n get disposalSignal() {\n return transport.disposalSignal;\n },\n dispose() {\n for (const controller of mutations) controller.abort();\n mutations.clear();\n queries.clear();\n transport.dispose();\n },\n get disposed() {\n return transport.disposed;\n },\n events: streams.events,\n get: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('GET', url, cfg),\n getHeaders: transport.getHeaders,\n headers: transport.headers,\n mutate,\n patch: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('PATCH', url, cfg),\n post: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('POST', url, cfg),\n put: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('PUT', url, cfg),\n queries,\n read: streams.read,\n request,\n [Symbol.dispose]() {\n this.dispose();\n },\n use: transport.use,\n };\n}\n","//#region src/random/uuid.ts\nfunction e() {\n\treturn crypto.randomUUID();\n}\n//#endregion\nexport { e as uuid };\n\n//# sourceMappingURL=uuid.js.map","import { uuid } from '@vielzeug/arsenal/random';\n\nimport type { Interceptor } from './transport';\n\n/**\n * Attaches a Bearer token `Authorization` header to every request.\n * The token can be a static string or an async function (useful for refresh flows).\n *\n * @example\n * ```ts\n * client.use(withBearerAuth(() => tokenStore.getAccessToken()));\n * ```\n */\nexport function withBearerAuth(token: string | (() => string | Promise<string>)): Interceptor {\n return async (ctx, next) => {\n const t = typeof token === 'function' ? await token() : token;\n\n return next(ctx.withHeaders({ authorization: `Bearer ${t}` }));\n };\n}\n\n/**\n * Adds a unique request ID to every request as a header.\n *\n * Defaults to `x-request-id` populated with `crypto.randomUUID()`.\n *\n * @example\n * ```ts\n * client.use(withRequestId());\n * client.use(withRequestId({ header: 'x-trace-id' }));\n * ```\n */\nexport function withRequestId(opts?: { generate?: () => string; header?: string }): Interceptor {\n const header = opts?.header ?? 'x-request-id';\n const generate = opts?.generate ?? uuid;\n\n return (ctx, next) => next(ctx.withHeaders({ [header]: generate() }));\n}\n\n/**\n * Logs each request's method, URL, status code, and duration.\n *\n * Defaults to `console.debug`. Supply a custom `logger` for structured logging.\n *\n * **Security note:** The full URL is logged, including any query parameters.\n * If your URLs may contain sensitive data (tokens, PII), provide a custom\n * `logger` that sanitizes the URL before writing to persistent logs.\n *\n * @example\n * ```ts\n * client.use(withLogging());\n * client.use(withLogging({ logger: (msg, meta) => logger.info(meta) }));\n * ```\n */\nexport function withLogging(opts?: {\n logger?: (msg: string, meta: { duration: number; method: string; status: number; url: string }) => void;\n}): Interceptor {\n const log =\n opts?.logger ??\n ((msg, meta) => {\n console.debug(msg, meta);\n });\n\n return async (ctx, next) => {\n const start = performance.now();\n const method = ((ctx.init as RequestInit).method ?? 'GET').toUpperCase();\n\n try {\n const res = await next(ctx);\n const duration = Math.round(performance.now() - start);\n\n log(`${method} ${ctx.url} ${res.status} (${duration}ms)`, {\n duration,\n method,\n status: res.status,\n url: ctx.url,\n });\n\n return res;\n } catch (err) {\n const duration = Math.round(performance.now() - start);\n\n log(`${method} ${ctx.url} ERR (${duration}ms)`, {\n duration,\n method,\n status: 0,\n url: ctx.url,\n });\n\n throw err;\n }\n };\n}\n"],"mappings":"mEAKA,IAAa,EAAb,MAAa,UAAqB,KAAM,CACtC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CAEA,OAAO,GAAG,EAAmC,CAC3C,OAAO,aAAe,CACxB,CACF,EAMa,EAAb,MAAa,UAAyB,CAAa,CACjD,IACA,OACA,OACA,KACA,QAEA,YAAY,EAAyG,CACnH,MAAM,EAAK,OAAO,EAClB,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,OACnB,KAAK,OAAS,EAAK,OACnB,KAAK,KAAO,EAAK,KACjB,KAAK,QAAU,EAAK,OACtB,CAEA,OAAO,aAAa,EAAe,EAAe,EAAgB,EAA+B,CAC/F,OAAO,IAAI,EAAiB,CAC1B,OACA,QAAS,EAAI,QACb,QAAS,EAAI,YAAc,QAAQ,EAAI,SACvC,SACA,OAAQ,EAAI,OACZ,KACF,CAAC,CACH,CAEA,OAAO,GAAG,EAAc,EAA0C,CAChE,OAAO,aAAe,IAAqB,IAAW,IAAA,IAAa,EAAI,SAAW,EACpF,CACF,EAOa,EAAb,cAAyC,CAAa,CACpD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAOa,EAAb,cAAyC,CAAa,CACpD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAMa,EAAb,cAAuC,CAAa,CAClD,IACA,OAEA,YAAY,EAAyE,CACnF,MAAM,EAAK,QAAS,CAAE,MAAO,EAAK,KAAM,CAAC,EACzC,KAAK,IAAM,EAAK,IAChB,KAAK,OAAS,EAAK,MACrB,CACF,EAOa,EAAb,cAAkD,CAAa,CAE7D,KAEA,YAAY,EAAgB,EAAe,CACzC,MAAM,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAG,CAAE,OAAM,CAAC,EACvE,KAAK,KAAO,CACd,CACF,EAGa,EAAb,cAA0C,CAAa,CACrD,YAAY,EAAoB,CAC9B,MAAM,aAAa,EAAW,UAAU,CAC1C,CACF,EAGa,EAAb,cAAuC,CAAa,CAAC,EAWrD,SAAgB,EACd,EACA,EACA,EACA,EAC+D,CAC/D,IAAM,EAAU,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAI/D,EAAS,GAAQ,OAgBvB,OAdI,aAAkB,OAAS,EAAO,OAAS,eACtC,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAG5D,aAAiB,aACf,EAAM,OAAS,eAAuB,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAE1F,IAAI,EAAkB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAGzD,aAAiB,OAAS,EAAM,OAAS,cAAiB,GAAQ,QAC9D,IAAI,EAAkB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,EAGvD,IAAI,EAAoB,CAAE,QAAO,UAAS,SAAQ,KAAI,CAAC,CAChE,CEhKA,IAAIA,EAAI,MAAM,UAAU,KAAM,CAC7B,YAAY,EAAG,EAAG,CACjB,MAAM,EAAG,CAAC,EAAG,KAAK,KAAO,WAAW,KAAM,OAAO,eAAe,KAAM,WAAW,SAAS,CAC3F,CACA,OAAO,GAAG,EAAG,CACZ,OAAO,aAAa,CACrB,CACD,EAAGC,EAAI,cAAcD,CAAE,CAAC,ECNxB,SAAS,EAAE,EAAG,EAAG,EAAG,CACnB,GAAI,IAAM,IAAK,GAAG,MAAO,YACzB,GAAI,IAAM,KAAM,MAAO,OACvB,GAAI,OAAO,GAAK,SAAU,MAAO,GAAG,EAAE,GACtC,GAAI,OAAO,GAAK,SAAU,OAAO,KAAK,UAAU,CAAC,EACjD,GAAI,EAAE,IAAI,CAAC,EAAG,MAAO,aACrB,GAAI,EAAE,IAAI,CAAC,EAAG,aAAa,KAAM,MAAO,SAAS,OAAO,MAAM,EAAE,QAAQ,CAAC,EAAI,UAAY,EAAE,YAAY,EAAE,GACzG,GAAI,aAAa,OAAQ,MAAO,WAAW,EAAE,OAAO,GAAG,EAAE,MAAM,GAC/D,GAAI,aAAa,IAAK,MAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAK,GAAM,EAAE,EAAG,EAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,EAAE,GACpF,GAAI,aAAa,IAAK,MAAO,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAG,KAAO,CAAC,EAAE,EAAG,EAAG,CAAC,EAAG,EAAE,EAAG,EAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAG,GAAI,CAAC,EAAG,KAAO,IAAM,EAAI,EAAE,cAAc,CAAC,EAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAG,KAAO,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,GACpN,GAAI,MAAM,QAAQ,CAAC,EAAG,MAAO,IAAI,EAAE,IAAK,GAAM,EAAE,EAAG,EAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,GACpE,IAAI,EAAI,OAAO,eAAe,CAAC,EAC/B,GAAI,IAAM,OAAO,WAAa,IAAM,KAAM,CACzC,GAAI,GAAG,kBAAoB,QAAS,MAAM,IAAIE,EAAE,0BAA0B,EAAE,aAAa,MAAQ,WAAW,EAC5G,OAAO,OAAO,CAAC,CAChB,CACA,IAAI,EAAI,EACR,MAAO,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,OAAQ,GAAM,EAAE,KAAO,IAAK,EAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAK,GAAM,GAAG,KAAK,UAAU,CAAC,EAAE,GAAG,EAAE,EAAE,GAAI,EAAG,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,EAC/H,CACA,SAAS,EAAE,EAAG,EAAG,CAChB,OAAO,EAAE,EAAG,EAAmB,IAAI,GAAK,CACzC,CCdA,SAAgB,EACd,EACA,EACA,EACA,EACA,EACa,CAWb,OAVI,IAAS,IAAA,IAAa,CAAC,EAAW,CAAI,EACjC,CACL,GAAG,EACH,KAAM,KAAK,UAAU,CAAI,EACzB,QAAS,CAAE,eAAgB,mBAAoB,GAAG,CAAQ,EAC1D,OAAQ,EAAO,YAAY,EAC3B,QACF,EAGK,CACL,GAAG,EACH,GAAI,IAAS,IAAA,IAAa,CAAQ,MAAiB,EACnD,UACA,OAAQ,EAAO,YAAY,EAC3B,QACF,CACF,CAEA,SAAgB,EAAW,EAAmC,CAC5D,OACE,aAAiB,UACjB,aAAiB,MACjB,aAAiB,iBACjB,OAAO,GAAU,UACjB,aAAiB,aACjB,YAAY,OAAO,CAAK,GACvB,OAAO,eAAmB,KAAe,aAAiB,cAE/D,CCxCA,IAAM,EAAqB,EAc3B,SAAS,EAAW,EAAa,GAAsB,CACrD,MAAO,CAAE,KAAM,IAAA,GAAW,MAAO,KAAM,aAAY,OAAQ,UAAW,UAAW,IAAA,EAAU,CAC7F,CAGA,SAAgB,EAAiB,EAA+E,CAC9G,IAAM,EAAU,IAAI,IACd,EAAY,IAAI,IAClB,EAAW,GAAS,QAAQ,SAAW,GAErC,EAAU,GAAwB,CACtC,IAAK,IAAM,IAAY,CAAC,GAAI,EAAU,IAAI,EAAK,CAAG,CAAC,GAAK,CAAC,CAAE,EAAG,EAAS,CACzE,EAEM,MAAwB,CAC5B,IAAK,IAAM,KAAS,EAAQ,OAAO,EAAG,EAAM,YAAY,MAAM,CAChE,EAEM,MAAoB,CACxB,IAAM,EAAO,CAAC,GAAG,EAAQ,OAAO,CAAC,CAAC,CAAC,IAAK,GAAU,EAAM,GAAG,EAE3D,EAAU,EACV,EAAQ,MAAM,EAEd,IAAK,IAAM,KAAO,EAAM,EAAO,CAAG,CACpC,EAEA,GAAS,QAAQ,iBACf,YACM,CACJ,EAAW,GACX,EAAM,CACR,EACA,CAAE,KAAM,EAAK,CACf,EAEA,IAAM,EAAY,GAAyB,CACzC,IAAM,EAAK,EAAK,CAAG,EACf,EAAQ,EAAQ,IAAI,CAAE,EAa1B,OAXK,IACH,EAAQ,CACN,WAAY,IAAA,GACZ,WAAY,IAAA,GACZ,MACA,QAAS,IAAA,GACT,SAAU,EAAQ,CACpB,EACA,EAAQ,IAAI,EAAI,CAAK,GAGhB,CACT,EAEM,GAAiB,EAAc,IAA+B,CAClE,GAAI,EAAU,OAAO,QAAQ,OAAO,IAAI,EAAqB,YAAY,CAAC,EAE1E,GAAI,CAAC,EAAM,WACT,OAAO,QAAQ,OAAW,MAAM,0CAA0C,EAAK,EAAM,GAAG,EAAE,EAAE,CAAC,EAE/F,IAAM,EAAY,EAAM,WAAW,WAAa,GAAS,WAAa,EAEtE,GACE,CAAC,GACD,EAAM,SAAS,SAAW,WAC1B,KAAK,IAAI,EAAI,EAAM,SAAS,UAAY,GACxC,CAAC,EAAM,SAAS,WAEhB,OAAO,QAAQ,QAAQ,EAAM,SAAS,IAAS,EAGjD,GAAI,EAAM,QAAS,OAAO,EAAM,QAEhC,IAAM,EAAa,IAAI,gBAEvB,EAAM,WAAa,EACnB,EAAM,SACJ,EAAM,SAAS,SAAW,UAAY,CAAE,GAAG,EAAM,SAAU,WAAY,EAAK,EAAI,CAAE,GAAG,EAAiB,EAAI,CAAE,EAC9G,EAAO,EAAM,GAAG,EAEhB,IAAM,EAAU,QAAQ,QAAQ,CAAC,CAC9B,SAAW,EAAM,YAAY,MAAM,CAAE,IAAK,EAAM,IAAK,OAAQ,EAAW,MAAO,CAAiB,CAAC,CAAC,CAClG,KACE,IACC,EAAM,SAAW,CAAE,OAAM,MAAO,KAAM,WAAY,GAAO,OAAQ,UAAW,UAAW,KAAK,IAAI,CAAE,EAClG,EAAM,WAAa,IAAA,GACnB,EAAM,QAAU,IAAA,GAChB,EAAO,EAAM,GAAG,EAET,GAER,GAAmB,CAClB,IAAM,EAAQ,aAAiB,MAAQ,EAAY,MAAM,OAAO,CAAK,CAAC,EAatE,KAXA,GAAM,SAAW,CACf,KAAM,EAAM,SAAS,SAAW,UAAY,EAAM,SAAS,KAAO,IAAA,GAClE,QACA,WAAY,GACZ,OAAQ,QACR,UAAW,KAAK,IAAI,CACtB,EACA,EAAM,WAAa,IAAA,GACnB,EAAM,QAAU,IAAA,GAChB,EAAO,EAAM,GAAG,EAEV,CACR,CACF,EAIF,MAFA,GAAM,QAAU,EAET,CACT,EAEA,MAAO,CACL,YACA,QACA,MAAS,EAAgC,EAAgD,CACvF,IAAM,EAAQ,EAAS,EAAW,GAAG,EAIrC,MAFA,GAAM,WAAa,EAEZ,EAAc,EAAO,GAAc,OAAS,EAAK,CAC1D,EACA,IAAO,EAA8B,CACnC,IAAM,EAAQ,EAAQ,IAAI,EAAK,CAAG,CAAC,EAEnC,OAAO,GAAO,SAAS,SAAW,UAAa,EAAM,SAAS,KAAa,IAAA,EAC7E,EACA,YAAe,EAAqC,CAClD,OAAQ,EAAQ,IAAI,EAAK,CAAG,CAAC,CAAC,EAAE,UAA0C,IAC5E,EACA,WAAW,EAAkC,CAC3C,IAAK,IAAM,KAAS,EAAQ,OAAO,EAE/B,EAAO,QAAU,EAAM,IAAI,QAAU,EAAO,OAAO,EAAM,IAAU,EAAK,CAAI,IAAM,EAAK,EAAM,IAAI,EAAM,CAAC,IAGpG,EAAM,SAAS,SAAW,YAAW,EAAM,SAAW,CAAE,GAAG,EAAM,SAAU,UAAW,CAAE,GAE5F,EAAO,EAAM,GAAG,EAGtB,EACA,MAAmB,CACjB,MAAO,CAAC,GAAG,EAAQ,OAAO,CAAC,CAAC,CAAC,IAAK,GAAU,EAAM,GAAG,CACvD,EACA,cAAqB,CACnB,IAAK,IAAM,KAAS,EAAQ,OAAO,EAAG,CACpC,GAAI,CAAC,EAAM,YAAc,EAAM,SAAS,SAAW,WAAa,EAAM,SAAS,WAAY,SAE3F,IAAM,EAAY,EAAM,WAAW,WAAa,GAAS,WAAa,EAElE,KAAK,IAAI,EAAI,EAAM,SAAS,WAAa,GAC3C,EAAgB,EAAO,EAAI,CAAC,CAAC,UAAY,CAClC,GAAiC,EAAK,EAAM,GAAG,EAA/C,CACP,CAAC,CAEL,CACF,EACA,IAAO,EAAe,EAAS,EAA2C,CACxE,IAAM,EAAQ,EAAS,CAAG,EAE1B,EAAM,SAAW,CACf,OACA,MAAO,KACP,WAAY,GACZ,OAAQ,UACR,UAAW,GAAY,WAAa,KAAK,IAAI,CAC/C,EACA,EAAO,CAAG,CACZ,EACA,UAAU,EAAe,EAAmC,CAC1D,IAAM,EAAK,EAAK,CAAG,EACb,EAAe,EAAU,IAAI,CAAE,GAAK,IAAI,IAK9C,OAHA,EAAa,IAAI,CAAQ,EACzB,EAAU,IAAI,EAAI,CAAY,MAEjB,CACX,EAAa,OAAO,CAAQ,EAExB,EAAa,OAAS,GAAG,EAAU,OAAO,CAAE,CAClD,CACF,CACF,CACF,CC1MA,eAAsB,EAAc,EAAe,EAA6B,OAA0B,CACxG,GAAI,IAAiB,MAAO,OAAO,EAEnC,GAAI,EAAI,SAAW,KAAO,EAAI,SAAW,KAAO,EAAI,SAAW,IAAK,OAEpE,GAAI,IAAiB,OAAQ,OAAO,EAAI,KAAK,EAE7C,GAAI,IAAiB,OAAQ,OAAO,EAAI,KAAK,EAE7C,GAAI,IAAiB,OAAQ,OAAO,EAAI,KAAK,EAE7C,GAAI,IAAiB,cAAe,OAAO,EAAI,YAAY,EAE3D,IAAM,EAAc,EAAI,QAAQ,IAAI,cAAc,GAAK,GAWvD,OATI,EAAY,SAAS,kBAAkB,GAAK,EAAY,SAAS,OAAO,EAAU,EAAI,KAAK,EAE3F,EAAY,WAAW,OAAO,EAAU,EAAI,KAAK,EAEjD,EAAY,WAAW,QAAQ,GAAK,EAAY,WAAW,QAAQ,GAAK,EAAY,WAAW,QAAQ,EAClG,EAAI,KAAK,EAIX,EAAI,KAAK,CAClB,CCFA,SAAS,EACP,EACA,EACA,EACc,CAcd,MAAO,CAZL,UACA,OACA,MACA,YAAY,EAA+C,CACzD,IAAM,EAAS,CAAE,GAAG,CAAQ,EAE5B,IAAK,GAAM,CAAC,EAAG,KAAM,OAAO,QAAQ,CAAO,EAAG,EAAO,EAAE,YAAY,GAAK,EAExE,OAAO,EAAiB,EAAK,EAAQ,CAAI,CAC3C,CAGK,CACT,CAEA,SAAgB,EAAU,GAAG,EAAiF,CAC5G,IAAM,EAAS,EAAQ,OAAQ,GAAwB,GAAK,IAAI,EAE5D,KAAO,SAAW,EAItB,OAFI,EAAO,SAAW,EAAU,EAAO,GAEhC,YAAY,IAAI,CAAM,CAC/B,CAUA,IAAa,EAAkB,IAE/B,SAAgB,EAAgB,EAAyB,CACvD,IAAK,GAAa,GAAK,CAAC,OAAO,SAAS,CAAS,IAAM,IAAc,IACnE,MAAM,IAAI,EAAa,yDAAyD,CAEpF,CAEA,SAAgB,EAAmB,EAAmB,EAAwD,CAK5G,OAJI,IAAc,IACT,GAAY,IAAA,GAGd,EAAU,YAAY,QAAQ,CAAS,EAAG,CAAQ,CAC3D,CAMA,SAAgB,EAAoB,EAAyB,CAAC,EAAG,CAC/D,GAAM,CACJ,UAAU,GACV,MAAO,EAAU,WAAW,MAC5B,QAAS,EAAiB,CAAC,EAC3B,UAAU,GACR,EAEJ,EAAgB,CAAO,EAEvB,IAAM,EAAwC,OAAO,YACnD,OAAO,QAAQ,CAAc,CAAC,CAAC,KAAK,CAAC,EAAG,KAAO,CAAC,EAAE,YAAY,EAAG,CAAC,CAAC,CACrE,EACM,EAAoB,IAAI,IACxB,EAAoB,IAAI,gBACxB,EAA8B,CAAC,EACjC,EAAoE,KACpE,EAAW,GAEf,SAAS,GAAwD,CAC/D,GAAI,EAAgB,OAAO,EAE3B,IAAM,EAAkD,GACtD,EAAQ,EAAI,IAAK,CAAE,GAAG,EAAI,KAAM,QAAS,EAAI,OAAQ,CAAC,EAUxD,MARA,GACE,EAAa,SAAW,EACpB,EACA,EAAa,aACV,EAAM,IAAiB,GAAQ,EAAY,EAAK,CAAI,EACrD,CACF,EAEC,CACT,CAEA,SAAS,EAAI,EAAsC,CAIjD,OAHA,EAAa,KAAK,CAAW,EAC7B,EAAiB,SAEJ,CACX,IAAM,EAAI,EAAa,QAAQ,CAAW,EAEtC,IAAM,KACR,EAAa,OAAO,EAAG,CAAC,EACxB,EAAiB,KAErB,CACF,CAEA,SAAS,EAAQ,EAAmD,CAClE,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAO,EAAG,CAClD,IAAM,EAAI,EAAI,YAAY,EAEtB,IAAU,IAAA,GAAW,OAAO,EAAc,GACzC,EAAc,GAAK,CAC1B,CACF,CAGA,SAAS,GAA+C,CACtD,MAAO,CAAE,GAAG,CAAc,CAC5B,CAMA,SAAS,EAAa,EAAqC,EAAwD,CACjH,IAAM,EAAa,EACf,OAAO,YAAY,OAAO,QAAQ,CAAU,CAAC,CAAC,KAAK,CAAC,EAAG,KAAO,CAAC,EAAE,YAAY,EAAG,CAAC,CAAC,CAAC,EACnF,IAAA,GAEJ,MAAO,CAAE,GAAG,EAAe,GAAG,EAAY,GAAG,CAAM,CACrD,CAGA,SAAS,EAAM,EAAiC,CAG9C,OAFA,EAAkB,IAAI,CAAE,MAEX,EAAkB,OAAO,CAAE,CAC1C,CAOA,SAAS,EAAS,EAII,CACpB,OAAO,EAAY,CAAC,CAAC,EAAiB,EAAI,IAAK,EAAI,QAAS,EAAI,IAAI,CAAC,CACvE,CAEA,SAAS,GAAkB,CACzB,IAAK,IAAM,IAAM,CAAC,GAAG,CAAiB,EAAG,EAAG,MAAM,EAClD,EAAkB,MAAM,CAC1B,CAEA,SAAS,GAAgB,CACnB,MAGJ,CADA,EAAW,GACX,EAAkB,MAAM,EAExB,IAAK,IAAM,KAAM,EAAmB,EAAG,MAAM,EAE7C,EAAkB,MAAM,EACxB,EAAa,OAAS,EACtB,EAAiB,IANO,CAO1B,CAEA,MAAO,CACL,UACA,YACA,WACA,IAAI,gBAAiB,CACnB,OAAO,EAAkB,MAC3B,EACA,UACA,IAAI,UAAW,CACb,OAAO,CACT,EACA,aAEA,YAAqB,CACnB,OAAO,CACT,EACA,UACA,eACA,QACA,KACF,CACF,CChLA,SAAgB,EAAS,EAAc,EAAc,EAAiB,EAAwB,CAC5F,IAAM,EAAY,EAAK,QAAQ,OAAQ,EAAE,EACrC,EAAY,EAAK,QAAQ,OAAQ,EAAE,EAEvC,EAAY,EAAU,QAAQ,gBAAiB,EAAG,IAAgB,CAChE,IAAM,EAAM,IAAS,GAErB,GAAI,GAA6B,KAAM,MAAM,IAAI,EAAkB,0BAA0B,EAAI,QAAQ,EAAK,EAAE,EAEhH,OAAO,mBAAmB,OAAO,CAAG,CAAC,CACvC,CAAC,EAED,IAAM,EAAM,GAAa,EAAY,GAAG,EAAU,GAAG,IAAc,GAAa,EAEhF,GAAI,CAAC,EAAO,OAAO,EAEnB,IAAM,EAAK,IAAI,gBAEf,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAK,EACzC,OAAU,IAAA,GAId,IAAI,MAAM,QAAQ,CAAK,EAAG,CACxB,IAAK,IAAM,KAAS,EACd,IAAU,IAAA,IACZ,EAAG,OAAO,EAAK,IAAU,KAAO,GAAK,OAAO,CAAK,CAAC,EAItD,QACF,CAEA,EAAG,OAAO,EAAK,IAAU,KAAO,GAAK,OAAO,CAAK,CAAC,CAFlD,CAKF,IAAM,EAAc,EAAG,SAAS,EAEhC,OAAO,EAAc,GAAG,IAAM,EAAI,SAAS,GAAG,EAAI,IAAM,MAAM,IAAgB,CAChF,CChEA,SAAS,EAAa,EAA8E,CAClG,IAAM,EAAa,IAAI,gBACjB,EAAW,EAAO,EAAW,MAAM,EAEzC,MAAO,CACL,KAAO,GAAsB,EAAS,KAAK,CAAK,EAChD,OAAS,IACP,EAAW,MAAM,EAEV,EAAS,OAAO,CAAU,GAEnC,CAAC,OAAO,gBAAiB,CACvB,OAAO,IACT,EACA,MAAQ,IACN,EAAW,MAAM,EAEV,EAAS,MAAM,CAAK,EAE/B,CACF,CAEA,eAAe,EACb,EACA,EACA,EACmF,CACnF,GAAI,EAAU,SAAU,MAAM,IAAI,EAAqB,SAAS,EAEhE,IAAM,EAAa,IAAI,gBACjB,EAAU,EAAU,MAAM,CAAU,EACpC,GAAU,EAAO,SAAW,EAAO,OAAS,IAAA,GAAY,MAAQ,QAAA,CAAS,YAAY,EACrF,EAAS,EACb,EAAO,SAAW,IAClB,EAAU,EAAO,OAAQ,EAAW,MAAM,CAC5C,EACI,EAAU,EAEd,GAAI,CACF,EAAU,EAAS,EAAU,QAAS,EAAK,EAAO,OAA8B,EAAO,KAAK,EAG5F,GAAM,CAAE,QAAS,EAAgB,GAAG,GAAS,EAC3C,EAFc,EAAU,aAAa,EAAO,OAG5C,EACA,EAAO,KACP,EACA,EAAO,WAAa,CAAC,CACvB,EACM,EAAW,MAAM,EAAU,SAAS,CACxC,QAAS,EACT,OACA,IAAK,CACP,CAAC,EAED,GAAI,CAAC,EAAS,GACZ,MAAM,EAAiB,aAAa,EAAU,MAAM,EAAS,KAAK,CAAC,CAAC,UAAY,EAAE,EAAG,EAAQ,CAAO,EAEtG,GAAI,CAAC,EAAS,KAAM,MAAM,IAAI,EAAkB,sBAAsB,EAEtE,MAAO,CAAE,aAAY,WAAU,SAAQ,CACzC,OAAS,EAAO,CAKd,MAJA,EAAQ,EAEJ,aAAiB,GAAoB,aAAiB,EAAyB,EAE7E,EAAqB,EAAO,EAAQ,EAAS,CAAM,CAC3D,CACF,CAGA,SAAgB,EAAc,EAA0B,CACtD,eAAgB,EACd,EACA,EACgC,CAChC,GAAM,CAAE,aAAY,WAAU,WAAY,MAAM,EAAK,EAAW,EAAK,CAAM,EACrE,EAAS,EAAS,KAAM,UAAU,EAClC,EAAU,IAAI,YAChB,EAAS,GACT,EAAQ,UACR,EAAO,GAEX,GAAI,CACF,OAAa,CACX,IAAM,EAAQ,MAAM,EAAO,KAAK,EAEhC,GAAI,EAAM,KAAM,MAEhB,GAAU,EAAQ,OAAO,EAAM,MAAO,CAAE,OAAQ,EAAK,CAAC,CAAC,CAAC,QAAQ,SAAU;CAAI,EAE9E,IAAI,EAEJ,MAAQ,EAAU,EAAO,QAAQ;CAAI,KAAO,IAAI,CAC9C,IAAM,EAAO,EAAO,MAAM,EAAG,CAAO,EAIpC,GAFA,EAAS,EAAO,MAAM,EAAU,CAAC,EAE7B,IAAS,GAAI,CACf,GAAI,IAAS,GAAI,CACf,IAAI,EAAkB,EAAK,SAAS;CAAI,EAAI,EAAK,MAAM,EAAG,EAAE,EAAI,EAEhE,GAAI,CACF,EAAS,KAAK,MAAM,CAAgB,CACtC,MAAQ,CAER,CAEA,KAAM,CAAE,KAAM,EAAa,OAAM,CACnC,CAEA,EAAO,GACP,EAAQ,UACR,QACF,CAEA,GAAI,EAAK,WAAW,GAAG,EAAG,SAE1B,IAAM,EAAY,EAAK,QAAQ,GAAG,EAC5B,EAAQ,IAAc,GAAK,EAAO,EAAK,MAAM,EAAG,CAAS,EACzD,GAAS,IAAc,GAAK,GAAK,EAAK,MAAM,EAAY,CAAC,EAAA,CAAG,QAAQ,KAAM,EAAE,EAE9E,IAAU,OAAQ,GAAQ,GAAG,EAAM,IAC9B,IAAU,UAAS,EAAQ,EACtC,CACF,CACF,QAAU,CACR,EAAO,YAAY,EACnB,EAAW,MAAM,EACjB,EAAQ,CACV,CACF,CAEA,eAAgB,EACd,EACA,EACmB,CACnB,GAAM,CAAE,aAAY,WAAU,WAAY,MAAM,EAAK,EAAW,EAAK,CAAM,EACrE,EAAS,EAAS,KAAM,UAAU,EAClC,EAAU,IAAI,YAChB,EAAS,GAEb,GAAI,CACF,OAAa,CACX,IAAM,EAAQ,MAAM,EAAO,KAAK,EAEhC,GAAI,EAAM,KAAM,CACd,GAAI,EAAO,QAAU,UAAY,EAAO,KAAK,EAC3C,GAAI,CACF,MAAM,KAAK,MAAM,CAAM,CACzB,MAAQ,CACN,MAAM,IAAI,EAAkB,iCAAiC,EAAO,MAAM,EAAG,GAAG,GAAG,CACrF,CAGF,KACF,CAEA,IAAM,EAAO,EAAQ,OAAO,EAAM,MAAO,CAAE,OAAQ,EAAK,CAAC,EAEzD,GAAI,EAAO,QAAU,SAAU,CAC7B,MAAM,EACN,QACF,CAEA,GAAU,EAEV,IAAI,EAEJ,MAAQ,EAAU,EAAO,QAAQ;CAAI,KAAO,IAAI,CAC9C,IAAM,EAAO,EAAO,MAAM,EAAG,CAAO,CAAC,CAAC,KAAK,EAE3C,KAAS,EAAO,MAAM,EAAU,CAAC,EAE5B,EAEL,GAAI,CACF,MAAM,KAAK,MAAM,CAAI,CACvB,MAAQ,CACN,MAAM,IAAI,EAAkB,iCAAiC,EAAK,MAAM,EAAG,GAAG,GAAG,CACnF,CACF,CACF,CACF,QAAU,CACR,EAAO,YAAY,EACnB,EAAW,MAAM,EACjB,EAAQ,CACV,CACF,CAEA,MAAO,CACL,OACE,EACA,EAA2B,CAAC,EACW,CACvC,OAAO,EAAW,GAChB,EAAa,EAAK,CAChB,GAAG,EACH,QAAS,CAAE,OAAQ,oBAAqB,gBAAiB,WAAY,GAAG,EAAO,OAAQ,EACvF,OAAQ,EAAU,EAAO,OAAQ,CAAM,CACzC,CAAC,CACH,CACF,EACA,KACE,EACA,EAA2D,CAAC,EAClC,CAC1B,OAAO,EAAW,GAAW,EAAW,EAAK,CAAE,GAAG,EAAQ,OAAQ,EAAU,EAAO,OAAQ,CAAM,CAAE,CAAC,CAAC,CACvG,CACF,CACF,CC9MA,SAAgB,EAAc,EAA0B,CAAC,EAAG,CAC1D,GAAM,CAAE,MAAO,EAAc,GAAG,GAAqB,EAC/C,EAAY,EAAoB,CAAgB,EAChD,EAAa,EAAiB,CAAE,GAAG,EAAc,OAAQ,EAAU,cAAe,CAAC,EACnF,EAAsB,EACtB,EAAU,EAAc,CAAS,EACjC,EAAY,IAAI,IAEtB,eAAe,EACb,EACA,EACA,EACA,EACA,EACA,EACY,CACZ,IAAM,EAAS,EAAK,OAChB,EAEJ,GAAI,CACF,EAAM,MAAM,EAAU,SAAS,CAAE,UAAS,OAAM,IAAK,CAAK,CAAC,CAC7D,OAAS,EAAK,CACZ,MAAM,EAAqB,EAAK,EAAG,EAAM,CAAM,CACjD,CAEA,GAAI,CAAC,EAAI,GAAI,CAKX,IAAM,EAAS,EAAI,QAAQ,IAAI,cAAc,CAAC,EAAE,SAAS,MAAM,GAAK,GAC9D,EAAO,MAAM,EAAI,KAAK,CAAC,CAAC,UAAY,EAAE,EACxC,EAAgB,EAEpB,GAAI,GAAQ,EACV,GAAI,CACF,EAAO,KAAK,MAAM,CAAI,CACxB,MAAQ,CAER,CAGF,MAAM,EAAiB,aAAa,EAAK,EAAM,EAAG,CAAI,CACxD,CAEA,IAAI,EAEJ,GAAI,CACF,EAAM,MAAM,EAAc,EAAK,GAAgB,MAAM,CACvD,OAAS,EAAK,CACZ,MAAM,EAAqB,EAAK,EAAG,EAAM,CAAM,CACjD,CAEA,GAAI,EACF,GAAI,CACF,OAAO,EAAO,MAAM,CAAG,CACzB,OAAS,EAAK,CACZ,MAAM,IAAI,EAA6B,EAAK,CAAG,CACjD,CAGF,OAAO,CACT,CAEA,eAAe,EACb,EACA,EACA,EAA+B,CAAC,EAChC,CACA,GAAI,EAAU,SAAU,MAAM,IAAI,EAAqB,SAAS,EAEhE,IAAM,EAAI,EAAO,YAAY,EAEzB,EAEJ,GAAI,CACF,EAAO,EAAS,EAAU,QAAS,EAAK,EAAO,OAA8B,EAAO,KAAK,CAC3F,OAAS,EAAK,CACZ,MAAM,EAAqB,EAAK,EAAG,CAAG,CACxC,CAEA,GAAM,CACJ,OACA,YACA,UACA,eACA,SACA,OAAQ,EACR,QAAS,GACP,EAEA,IAAe,IAAA,IAAW,EAAgB,CAAU,EAExD,IAAM,EAAY,IAAI,gBAChB,EAAU,EAAU,MAAM,CAAS,EACnC,EAAS,EAAmB,GAAc,EAAU,WAAW,EAAG,EAAU,EAAW,EAAU,MAAM,CAAC,EACxG,CAAE,QAAS,EAAa,GAAG,GAAa,EAC5C,EACA,EAAU,aAAa,CAAO,EAC9B,EACA,EACA,GAAa,CAAC,CAChB,EAEA,GAAI,CACF,OAAO,MAAM,EACX,EACA,EACA,EACA,EACA,EACA,CACF,CACF,QAAU,CACR,EAAQ,CACV,CACF,CAsBA,MAAO,CACL,WAAY,CACV,EAAU,UAAU,EACpB,EAAW,UAAU,EACrB,IAAK,IAAM,KAAc,EAAW,EAAW,MAAM,CACvD,EACA,QAAuC,EAAQ,IAA+B,EAAc,SAAU,EAAK,CAAG,EAC9G,IAAI,gBAAiB,CACnB,OAAO,EAAU,cACnB,EACA,SAAU,CACR,IAAK,IAAM,KAAc,EAAW,EAAW,MAAM,EACrD,EAAU,MAAM,EAChB,EAAQ,MAAM,EACd,EAAU,QAAQ,CACpB,EACA,IAAI,UAAW,CACb,OAAO,EAAU,QACnB,EACA,OAAQ,EAAQ,OAChB,KAAoC,EAAQ,IAA+B,EAAc,MAAO,EAAK,CAAG,EACxG,WAAY,EAAU,WACtB,QAAS,EAAU,QACnB,YA3CuB,IAA4C,CACnE,GAAI,EAAU,SAAU,MAAM,IAAI,EAAqB,SAAS,EAEhE,IAAM,EAAa,IAAI,gBAEvB,EAAU,IAAI,CAAU,EAExB,IAAM,EAAS,EAAU,EAAQ,OAAQ,EAAW,OAAQ,EAAU,cAAc,GAAK,EAAW,OAEpG,GAAI,CACF,IAAM,EAAO,MAAM,EAAQ,QAAQ,CAAE,QAAO,CAAC,EAI7C,OAFA,MAAM,EAAQ,YAAY,EAAM,CAAO,EAEhC,CACT,QAAU,CACR,EAAU,OAAO,CAAU,CAC7B,CACF,EA0BE,OAAsC,EAAQ,IAA+B,EAAc,QAAS,EAAK,CAAG,EAC5G,MAAqC,EAAQ,IAA+B,EAAc,OAAQ,EAAK,CAAG,EAC1G,KAAoC,EAAQ,IAA+B,EAAc,MAAO,EAAK,CAAG,EACxG,UACA,KAAM,EAAQ,KACd,UACA,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,EACA,IAAK,EAAU,GACjB,CACF,CCnMA,SAAS,GAAI,CACZ,OAAO,OAAO,WAAW,CAC1B,CCUA,SAAgB,EAAe,EAA+D,CAC5F,OAAO,MAAO,EAAK,IAAS,CAC1B,IAAM,EAAI,OAAO,GAAU,WAAa,MAAM,EAAM,EAAI,EAExD,OAAO,EAAK,EAAI,YAAY,CAAE,cAAe,UAAU,GAAI,CAAC,CAAC,CAC/D,CACF,CAaA,SAAgB,EAAc,EAAkE,CAC9F,IAAM,EAAS,GAAM,QAAU,eACzB,EAAW,GAAM,UAAY,EAEnC,OAAQ,EAAK,IAAS,EAAK,EAAI,YAAY,EAAG,GAAS,EAAS,CAAE,CAAC,CAAC,CACtE,CAiBA,SAAgB,EAAY,EAEZ,CACd,IAAM,EACJ,GAAM,UACJ,EAAK,IAAS,CACd,QAAQ,MAAM,EAAK,CAAI,CACzB,GAEF,OAAO,MAAO,EAAK,IAAS,CAC1B,IAAM,EAAQ,YAAY,IAAI,EACxB,GAAW,EAAI,KAAqB,QAAU,MAAA,CAAO,YAAY,EAEvE,GAAI,CACF,IAAM,EAAM,MAAM,EAAK,CAAG,EACpB,EAAW,KAAK,MAAM,YAAY,IAAI,EAAI,CAAK,EASrD,OAPA,EAAI,GAAG,EAAO,GAAG,EAAI,IAAI,GAAG,EAAI,OAAO,IAAI,EAAS,KAAM,CACxD,WACA,SACA,OAAQ,EAAI,OACZ,IAAK,EAAI,GACX,CAAC,EAEM,CACT,OAAS,EAAK,CACZ,IAAM,EAAW,KAAK,MAAM,YAAY,IAAI,EAAI,CAAK,EASrD,MAPA,EAAI,GAAG,EAAO,GAAG,EAAI,IAAI,QAAQ,EAAS,KAAM,CAC9C,WACA,SACA,OAAQ,EACR,IAAK,EAAI,GACX,CAAC,EAEK,CACR,CACF,CACF"}
1
+ {"version":3,"file":"courier.cjs","names":["e","t","e"],"sources":["../src/errors.ts","../../arsenal/dist/errors.js","../../arsenal/dist/object/hash.js","../src/query.ts","../src/response.ts","../src/serialize.ts","../src/transport.ts","../src/url.ts","../src/stream.ts","../src/courier.ts","../../arsenal/dist/random/uuid.js","../src/interceptors.ts"],"sourcesContent":["/**\n * Base class for all courier errors.\n * Use `instanceof CourierError` to catch any courier-originated error in one branch.\n * Use `CourierHttpError.is(e, status?)` to check for a specific HTTP status code.\n */\nexport class CourierError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when the server responds with a non-2xx HTTP status code.\n * Use `HttpError.is(e, status?)` to narrow to a specific status.\n */\nexport class CourierHttpError extends CourierError {\n readonly url: string;\n readonly method: string;\n readonly status: number;\n readonly data: unknown;\n readonly headers: Headers;\n\n constructor(opts: { data: unknown; headers: Headers; message: string; method: string; status: number; url: string }) {\n super(opts.message);\n this.url = opts.url;\n this.method = opts.method;\n this.status = opts.status;\n this.data = opts.data;\n this.headers = opts.headers;\n }\n\n static fromResponse(res: Response, data: unknown, method: string, url: string): CourierHttpError {\n return new CourierHttpError({\n data,\n headers: res.headers,\n message: res.statusText || `HTTP ${res.status}`,\n method,\n status: res.status,\n url,\n });\n }\n\n static is(err: unknown, status?: number): err is CourierHttpError {\n return err instanceof CourierHttpError && (status === undefined || err.status === status);\n }\n}\n\n/**\n * Thrown when a fetch fails due to a network-level error (DNS, TCP, CORS, etc.)\n * with no HTTP response. Distinct from `HttpError` so callers never need to check\n * for a missing `status` field.\n */\nexport class CourierNetworkError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a request is aborted via `AbortSignal.timeout()` or a caller-supplied\n * timeout option. Distinct from `AbortError` so callers can show retry UI on timeouts\n * without checking any `kind` discriminant.\n */\nexport class CourierTimeoutError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a request is cancelled via a caller-supplied `AbortSignal` or\n * `cancelAll()` / `dispose()`. Safe to ignore in most UI handlers.\n */\nexport class CourierAbortError extends CourierError {\n readonly url: string;\n readonly method: string;\n\n constructor(opts: { cause?: unknown; message: string; method: string; url: string }) {\n super(opts.message, { cause: opts.cause });\n this.url = opts.url;\n this.method = opts.method;\n }\n}\n\n/**\n * Thrown when a response body fails schema validation (via the `schema` option).\n * Distinct from the HTTP error classes so callers can separately handle network failures\n * vs. data contract violations without inspecting the error shape.\n */\nexport class CourierSchemaValidationError extends CourierError {\n /** The raw (pre-validation) response body that failed parsing. */\n readonly data: unknown;\n\n constructor(cause: unknown, data: unknown) {\n super(cause instanceof Error ? cause.message : String(cause), { cause });\n this.data = data;\n }\n}\n\n/** Thrown when a method is called on a disposed client instance. */\nexport class CourierDisposedError extends CourierError {\n constructor(clientName: string) {\n super(`[courier] ${clientName} disposed`);\n }\n}\n\n/** Thrown when a response body cannot be read or parsed. */\nexport class CourierParseError extends CourierError {}\n\n/**\n * Classify an error thrown by `fetch` or an abort signal into the appropriate\n * courier error class. Signal reason is checked first so a timed-out signal\n * always produces `TimeoutError` even when `fetch` throws a generic Error.\n *\n * We check `.name` rather than `instanceof DOMException` because `AbortSignal.timeout()`\n * sets reason to the *native* Node.js DOMException which may differ from the environment's\n * global DOMException (e.g. jsdom), causing `instanceof` checks to fail cross-realm.\n */\nexport function classifyRequestError(\n cause: unknown,\n method: string,\n url: string,\n signal?: AbortSignal,\n): CourierNetworkError | CourierTimeoutError | CourierAbortError {\n const message = cause instanceof Error ? cause.message : String(cause);\n\n // Signal reason is authoritative — a timed-out signal carries a TimeoutError reason\n // regardless of what error `fetch` actually threw.\n const reason = signal?.reason;\n\n if (reason instanceof Error && reason.name === 'TimeoutError') {\n return new CourierTimeoutError({ cause, message, method, url });\n }\n\n if (cause instanceof DOMException) {\n if (cause.name === 'TimeoutError') return new CourierTimeoutError({ cause, message, method, url });\n\n return new CourierAbortError({ cause, message, method, url });\n }\n\n if ((cause instanceof Error && cause.name === 'AbortError') || signal?.aborted) {\n return new CourierAbortError({ cause, message, method, url });\n }\n\n return new CourierNetworkError({ cause, message, method, url });\n}\n","//#region src/errors.ts\nvar e = class extends Error {\n\tconstructor(e, t) {\n\t\tsuper(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);\n\t}\n}, t = class extends e {};\n//#endregion\nexport { e as ArsenalError, t as ArsenalSerializationError };\n\n//# sourceMappingURL=errors.js.map","import { ArsenalSerializationError as e } from \"../errors.js\";\n//#region src/object/hash.ts\nfunction t(n, r, i) {\n\tif (n === void 0) return \"undefined\";\n\tif (n === null) return \"null\";\n\tif (typeof n == \"bigint\") return `${n}n`;\n\tif (typeof n != \"object\") return JSON.stringify(n);\n\tif (i.has(n)) return \"[Circular]\";\n\tif (i.add(n), n instanceof Date) return `[Date:${Number.isNaN(n.getTime()) ? \"Invalid\" : n.toISOString()}]`;\n\tif (n instanceof RegExp) return `[RegExp:${n.source}/${n.flags}]`;\n\tif (n instanceof Set) return `[Set:${[...n].map((e) => t(e, r, i)).sort().join(\",\")}]`;\n\tif (n instanceof Map) return `[Map:${[...n.entries()].map(([e, n]) => [t(e, r, i), t(n, r, i)]).sort(([e, t], [n, r]) => e === n ? t.localeCompare(r) : e.localeCompare(n)).map(([e, t]) => `${e}=>${t}`).join(\",\")}]`;\n\tif (Array.isArray(n)) return `[${n.map((e) => t(e, r, i)).join(\",\")}]`;\n\tlet a = Object.getPrototypeOf(n);\n\tif (a !== Object.prototype && a !== null) {\n\t\tif (r?.onClassInstance === \"throw\") throw new e(`hash: unsupported type ${n.constructor?.name ?? \"unknown\"}`);\n\t\treturn String(n);\n\t}\n\tlet o = n;\n\treturn `{${Object.keys(o).filter((e) => o[e] !== void 0).sort().map((e) => `${JSON.stringify(e)}:${t(o[e], r, i)}`).join(\",\")}}`;\n}\nfunction n(e, n) {\n\treturn t(e, n, /* @__PURE__ */ new Set());\n}\n//#endregion\nexport { n as hash };\n\n//# sourceMappingURL=hash.js.map","import { hash } from '@vielzeug/arsenal/object';\nimport { CourierDisposedError } from './errors';\nimport type { AsyncState, QueryCache, QueryContext, QueryDefinition, QueryKey, Unsubscribe } from './types';\n\nconst DEFAULT_STALE_TIME = 0;\nconst DEFAULT_GC_TIME = 5 * 60_000;\n\ntype Entry = {\n controller: AbortController | undefined;\n definition: QueryDefinition<unknown> | undefined;\n key: QueryKey;\n promise: Promise<unknown> | undefined;\n snapshot: AsyncState<unknown>;\n};\n\ntype CancellableQueryCache = QueryCache & {\n cancelAll(): void;\n};\n\nfunction loading<T>(isFetching = false): AsyncState<T> {\n return { data: undefined, error: null, isFetching, status: 'loading', updatedAt: undefined };\n}\n\n/** Transport-agnostic cache. Queries are identified by explicit keys and fetch definitions.\n * Entries with no subscribers are garbage-collected after `gcTime` (default 5 min; `Infinity` disables). */\nexport function createQueryCache(options?: {\n gcTime?: number;\n signal?: AbortSignal;\n staleTime?: number;\n}): CancellableQueryCache {\n const staleTime = options?.staleTime ?? DEFAULT_STALE_TIME;\n const gcTime = options?.gcTime ?? DEFAULT_GC_TIME;\n const entries = new Map<string, Entry>();\n const listeners = new Map<string, Set<Unsubscribe>>();\n let disposed = options?.signal?.aborted ?? false;\n let gcTimer: ReturnType<typeof setTimeout> | undefined;\n\n const hasSubscribers = (id: string): boolean => (listeners.get(id)?.size ?? 0) > 0;\n\n const notify = (key: QueryKey): void => {\n for (const listener of [...(listeners.get(hash(key)) ?? [])]) listener();\n };\n\n const scheduleGc = (): void => {\n if (gcTime === Number.POSITIVE_INFINITY || disposed) {\n if (gcTimer) clearTimeout(gcTimer);\n gcTimer = undefined;\n return;\n }\n\n if (gcTimer) clearTimeout(gcTimer);\n\n let earliest: number | undefined;\n\n for (const entry of entries.values()) {\n if (entry.snapshot.status !== 'success' || entry.promise) continue;\n if (hasSubscribers(hash(entry.key))) continue;\n\n const expiresAt = entry.snapshot.updatedAt + gcTime;\n\n if (earliest === undefined || expiresAt < earliest) earliest = expiresAt;\n }\n\n if (earliest === undefined) {\n gcTimer = undefined;\n return;\n }\n\n gcTimer = setTimeout(runGc, Math.max(0, earliest - Date.now()));\n };\n\n const runGc = (): void => {\n const now = Date.now();\n\n for (const [id, entry] of entries) {\n if (entry.snapshot.status !== 'success' || entry.promise) continue;\n if (hasSubscribers(id)) continue;\n if (now - entry.snapshot.updatedAt >= gcTime) entries.delete(id);\n }\n\n scheduleGc();\n };\n\n const cancelAll = (): void => {\n for (const entry of entries.values()) entry.controller?.abort();\n };\n\n const clear = (): void => {\n const keys = [...entries.values()].map((entry) => entry.key);\n\n cancelAll();\n entries.clear();\n\n if (gcTimer) {\n clearTimeout(gcTimer);\n gcTimer = undefined;\n }\n\n for (const key of keys) notify(key);\n };\n\n options?.signal?.addEventListener(\n 'abort',\n () => {\n disposed = true;\n clear();\n },\n { once: true },\n );\n\n const entryFor = (key: QueryKey): Entry => {\n const id = hash(key);\n let entry = entries.get(id);\n\n if (!entry) {\n entry = {\n controller: undefined,\n definition: undefined,\n key,\n promise: undefined,\n snapshot: loading(),\n };\n entries.set(id, entry);\n }\n\n return entry;\n };\n\n const fetchEntry = <T>(entry: Entry, force: boolean): Promise<T> => {\n if (disposed) return Promise.reject(new CourierDisposedError('QueryCache'));\n\n if (!entry.definition)\n return Promise.reject(new Error(`No fetch function registered for query ${hash(entry.key)}.`));\n\n const entryStaleTime = entry.definition.staleTime ?? staleTime;\n\n if (\n !force &&\n entry.snapshot.status === 'success' &&\n Date.now() - entry.snapshot.updatedAt < entryStaleTime &&\n !entry.snapshot.isFetching\n ) {\n return Promise.resolve(entry.snapshot.data as T);\n }\n\n if (entry.promise) return entry.promise as Promise<T>;\n\n const controller = new AbortController();\n\n entry.controller = controller;\n entry.snapshot =\n entry.snapshot.status === 'success' ? { ...entry.snapshot, isFetching: true } : { ...loading<unknown>(true) };\n notify(entry.key);\n\n const promise = Promise.resolve()\n .then(() => entry.definition?.fetch({ key: entry.key, signal: controller.signal } as QueryContext))\n .then(\n (data) => {\n entry.snapshot = { data, error: null, isFetching: false, status: 'success', updatedAt: Date.now() };\n entry.controller = undefined;\n entry.promise = undefined;\n notify(entry.key);\n scheduleGc();\n\n return data;\n },\n (cause: unknown) => {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n\n entry.snapshot = {\n data: entry.snapshot.status === 'success' ? entry.snapshot.data : undefined,\n error,\n isFetching: false,\n status: 'error',\n updatedAt: Date.now(),\n };\n entry.controller = undefined;\n entry.promise = undefined;\n notify(entry.key);\n\n throw error;\n },\n );\n\n entry.promise = promise;\n\n return promise as Promise<T>;\n };\n\n return {\n cancelAll,\n clear,\n fetch<T>(definition: QueryDefinition<T>, fetchOptions?: { force?: boolean }): Promise<T> {\n const entry = entryFor(definition.key);\n\n entry.definition = definition as QueryDefinition<unknown>;\n\n return fetchEntry<T>(entry, fetchOptions?.force ?? false);\n },\n get<T>(key: QueryKey): T | undefined {\n const entry = entries.get(hash(key));\n\n return entry?.snapshot.status === 'success' ? (entry.snapshot.data as T) : undefined;\n },\n getSnapshot<T>(key: QueryKey): AsyncState<T> | null {\n return (entries.get(hash(key))?.snapshot as AsyncState<T> | undefined) ?? null;\n },\n invalidate(prefix: readonly unknown[], invalidateOptions?: { refetch?: boolean }): void {\n const refetch = invalidateOptions?.refetch ?? false;\n let invalidated = false;\n\n for (const entry of entries.values()) {\n const matches = prefix.length <= entry.key.length && prefix.every((atom, index) => atom === entry.key[index]);\n\n if (matches) {\n if (entry.snapshot.status === 'success') entry.snapshot = { ...entry.snapshot, updatedAt: 0 };\n\n notify(entry.key);\n\n if (refetch && entry.definition && !entry.promise) {\n void fetchEntry(entry, true).catch(() => {\n /* Error surfaces through cache snapshot; suppress unhandled rejection. */\n });\n }\n\n invalidated = true;\n }\n }\n\n if (invalidated) scheduleGc();\n },\n keys(): QueryKey[] {\n return [...entries.values()].map((entry) => entry.key);\n },\n set<T>(key: QueryKey, data: T, setOptions?: { updatedAt?: number }): void {\n const entry = entryFor(key);\n\n entry.snapshot = {\n data,\n error: null,\n isFetching: false,\n status: 'success',\n updatedAt: setOptions?.updatedAt ?? Date.now(),\n };\n notify(key);\n scheduleGc();\n },\n subscribe(key: QueryKey, listener: () => void): Unsubscribe {\n const id = hash(key);\n const keyListeners = listeners.get(id) ?? new Set<Unsubscribe>();\n\n keyListeners.add(listener);\n listeners.set(id, keyListeners);\n\n return () => {\n keyListeners.delete(listener);\n\n if (keyListeners.size === 0) {\n listeners.delete(id);\n scheduleGc();\n }\n };\n },\n };\n}\n","/** Response parsing strategy. 'raw' returns the Response object directly. */\nexport type ResponseType = 'auto' | 'json' | 'text' | 'blob' | 'arrayBuffer' | 'raw';\n\nasync function parseJson(res: Response): Promise<unknown> {\n const text = (await res.text()).trim();\n\n return text ? JSON.parse(text) : undefined;\n}\n\nexport async function parseResponse(res: Response, responseType: ResponseType = 'auto'): Promise<unknown> {\n if (responseType === 'raw') return res;\n\n if (res.status === 204 || res.status === 205 || res.status === 304) return;\n\n if (responseType === 'json') return parseJson(res);\n\n if (responseType === 'text') return res.text();\n\n if (responseType === 'blob') return res.blob();\n\n if (responseType === 'arrayBuffer') return res.arrayBuffer();\n\n const contentType = res.headers.get('content-type') ?? '';\n\n if (contentType.includes('application/json') || contentType.includes('+json')) return parseJson(res);\n\n if (contentType.startsWith('text/')) return res.text();\n\n if (contentType.startsWith('image/') || contentType.startsWith('audio/') || contentType.startsWith('video/')) {\n return res.blob();\n }\n\n // Unknown content-type — fall back to text, which is always safe to read and debug.\n return res.text();\n}\n","/**\n * Build a `RequestInit` object from the request components, handling body serialisation.\n * Plain objects/arrays are JSON-serialised and `content-type: application/json` is added.\n * BodyInit values (FormData, Blob, etc.) are forwarded as-is.\n */\nexport function buildRequestInit(\n method: string,\n headers: Record<string, string>,\n body: unknown,\n signal: AbortSignal | undefined,\n rest: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'>,\n): RequestInit {\n if (body !== undefined && !isBodyInit(body)) {\n return {\n ...rest,\n body: JSON.stringify(body),\n headers: { 'content-type': 'application/json', ...headers },\n method: method.toUpperCase(),\n signal,\n };\n }\n\n return {\n ...rest,\n ...(body !== undefined && { body: body as BodyInit }),\n headers,\n method: method.toUpperCase(),\n signal,\n };\n}\n\nexport function isBodyInit(value: unknown): value is BodyInit {\n return (\n value instanceof FormData ||\n value instanceof Blob ||\n value instanceof URLSearchParams ||\n typeof value === 'string' ||\n value instanceof ArrayBuffer ||\n ArrayBuffer.isView(value) ||\n (typeof ReadableStream !== 'undefined' && value instanceof ReadableStream)\n );\n}\n","import { CourierError } from './errors';\n\n/**\n * Immutable request context passed through the interceptor pipeline.\n *\n * **Never mutate `init` or `headers` directly.** Use `ctx.withHeaders(updates)` to\n * produce a new context with merged headers — this is the safe, idiomatic pattern\n * for interceptors that need to add or override headers.\n *\n * @example\n * ```ts\n * // Correct — returns a new context\n * return next(ctx.withHeaders({ authorization: `Bearer ${token}` }));\n *\n * // Wrong — mutates shared state, risks stomping other interceptors\n * ctx.init.headers = { ...ctx.init.headers, authorization: `Bearer ${token}` };\n * ```\n */\nexport type FetchContext = {\n readonly headers: Readonly<Record<string, string>>;\n readonly init: Readonly<Omit<RequestInit, 'headers'>>;\n readonly url: string;\n /** Returns a new `FetchContext` with the given header overrides merged in (lowercase keys). */\n withHeaders(updates: Record<string, string>): FetchContext;\n};\n\nfunction makeFetchContext(\n url: string,\n headers: Record<string, string>,\n init: Omit<RequestInit, 'headers'>,\n): FetchContext {\n const ctx: FetchContext = {\n headers,\n init,\n url,\n withHeaders(updates: Record<string, string>): FetchContext {\n const merged = { ...headers };\n\n for (const [k, v] of Object.entries(updates)) merged[k.toLowerCase()] = v;\n\n return makeFetchContext(url, merged, init);\n },\n };\n\n return ctx;\n}\n\nexport function anySignal(...signals: ReadonlyArray<AbortSignal | null | undefined>): AbortSignal | undefined {\n const active = signals.filter((s): s is AbortSignal => s != null);\n\n if (active.length === 0) return undefined;\n\n if (active.length === 1) return active[0];\n\n return AbortSignal.any(active);\n}\nexport type Interceptor = (ctx: FetchContext, next: (ctx: FetchContext) => Promise<Response>) => Promise<Response>;\n\nexport type TransportOptions = {\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n headers?: Record<string, string>;\n timeout?: number;\n};\n\nexport const DEFAULT_TIMEOUT = 30_000;\n\nexport function validateTimeout(timeoutMs: number): void {\n if ((timeoutMs <= 0 || !Number.isFinite(timeoutMs)) && timeoutMs !== Number.POSITIVE_INFINITY) {\n throw new CourierError('[courier] timeout must be a positive number or Infinity');\n }\n}\n\nexport function buildTimeoutSignal(timeoutMs: number, external?: AbortSignal | null): AbortSignal | undefined {\n if (timeoutMs === Number.POSITIVE_INFINITY) {\n return external ?? undefined;\n }\n\n return anySignal(AbortSignal.timeout(timeoutMs), external);\n}\n\n/**\n * Shared transport core: interceptor pipeline, header management, AbortController lifecycle.\n * HTTP requests and streams build on this to avoid duplicating infrastructure.\n */\nexport function createTransportCore(opts: TransportOptions = {}) {\n const {\n baseUrl = '',\n fetch: fetchFn = globalThis.fetch,\n headers: initialHeaders = {},\n timeout = DEFAULT_TIMEOUT,\n } = opts;\n\n validateTimeout(timeout);\n\n const globalHeaders: Record<string, string> = Object.fromEntries(\n Object.entries(initialHeaders).map(([k, v]) => [k.toLowerCase(), v]),\n );\n const activeControllers = new Set<AbortController>();\n const disposeController = new AbortController();\n const interceptors: Interceptor[] = [];\n let cachedPipeline: ((ctx: FetchContext) => Promise<Response>) | null = null;\n let disposed = false;\n\n function getPipeline(): (ctx: FetchContext) => Promise<Response> {\n if (cachedPipeline) return cachedPipeline;\n\n const base: (ctx: FetchContext) => Promise<Response> = (ctx) =>\n fetchFn(ctx.url, { ...ctx.init, headers: ctx.headers });\n\n cachedPipeline =\n interceptors.length === 0\n ? base\n : interceptors.reduceRight<(ctx: FetchContext) => Promise<Response>>(\n (next, interceptor) => (ctx) => interceptor(ctx, next),\n base,\n );\n\n return cachedPipeline;\n }\n\n function use(interceptor: Interceptor): () => void {\n interceptors.push(interceptor);\n cachedPipeline = null;\n\n return () => {\n const i = interceptors.indexOf(interceptor);\n\n if (i !== -1) {\n interceptors.splice(i, 1);\n cachedPipeline = null;\n }\n };\n }\n\n function setHeaders(updates: Record<string, string | undefined>): void {\n for (const [key, value] of Object.entries(updates)) {\n const k = key.toLowerCase();\n\n if (value === undefined) delete globalHeaders[k];\n else globalHeaders[k] = value;\n }\n }\n\n /** Returns a read-only snapshot of the current global headers. */\n function getHeaders(): Readonly<Record<string, string>> {\n return { ...globalHeaders };\n }\n\n /**\n * Merge global headers with optional per-request and extra headers.\n * Per-request keys are normalised to lowercase.\n */\n function mergeHeaders(perRequest?: Record<string, string>, extra?: Record<string, string>): Record<string, string> {\n const normalized = perRequest\n ? Object.fromEntries(Object.entries(perRequest).map(([k, v]) => [k.toLowerCase(), v]))\n : undefined;\n\n return { ...globalHeaders, ...normalized, ...extra };\n }\n\n /** Register an AbortController for lifecycle tracking (cancelAll / dispose). Returns an untrack fn. */\n function track(ac: AbortController): () => void {\n activeControllers.add(ac);\n\n return () => activeControllers.delete(ac);\n }\n\n /**\n * Dispatch a request through the interceptor pipeline.\n * Accepts a plain `{ url, headers, init }` object and promotes it to a\n * full `FetchContext` with `withHeaders()` before entering the pipeline.\n */\n function dispatch(raw: {\n headers: Record<string, string>;\n init: Omit<RequestInit, 'headers'>;\n url: string;\n }): Promise<Response> {\n return getPipeline()(makeFetchContext(raw.url, raw.headers, raw.init));\n }\n\n function cancelAll(): void {\n for (const ac of [...activeControllers]) ac.abort();\n activeControllers.clear();\n }\n\n function dispose(): void {\n if (disposed) return;\n\n disposed = true;\n disposeController.abort();\n\n for (const ac of activeControllers) ac.abort();\n\n activeControllers.clear();\n interceptors.length = 0;\n cachedPipeline = null;\n }\n\n return {\n baseUrl,\n cancelAll,\n dispatch,\n get disposalSignal() {\n return disposeController.signal;\n },\n dispose,\n get disposed() {\n return disposed;\n },\n getHeaders,\n /** Returns the configured request timeout in ms. */\n getTimeout(): number {\n return timeout;\n },\n mergeHeaders,\n setHeaders,\n track,\n use,\n };\n}\n\nexport type TransportCore = ReturnType<typeof createTransportCore>;\n","import { CourierParseError } from './errors';\nimport type { ResponseType } from './response';\n\ntype QueryScalar = string | number | boolean | null;\n\nexport type ParamValue = QueryScalar | readonly QueryScalar[] | undefined;\nexport type Params = Record<string, ParamValue>;\n\n// Type-safe path params: extracts {param} placeholders from a path string\ntype ExtractPathParams<P extends string> = P extends `${string}{${infer K}}${infer R}`\n ? K | ExtractPathParams<R>\n : never;\n\nexport type PathConfig<P extends string> = [ExtractPathParams<P>] extends [never]\n ? { params?: never }\n : { params: Record<ExtractPathParams<P>, string | number | boolean> };\n\nexport type CourierRequestConfig<P extends string = string, T = unknown> = PathConfig<P> & {\n /** Request body. Plain objects → JSON. BodyInit values passed as-is. */\n body?: unknown;\n /** Query string parameters. */\n query?: Params;\n /** Response parsing strategy. */\n responseType?: ResponseType;\n /**\n * Optional schema for response validation. Any object with a `parse(data)` method\n * works — e.g. a `@vielzeug/spell` schema or a plain validator function wrapper.\n * Called after the response body is parsed; throws if validation fails.\n * The schema's return type must be assignable to `T`.\n */\n schema?: { parse(data: unknown): T };\n /** Request timeout in ms. Overrides client default. */\n timeout?: number;\n};\n\nexport type HttpRequestConfig<P extends string = string, T = unknown> = CourierRequestConfig<P, T> & {\n /** Raw fetch options for advanced use (credentials, cache, mode, referrer, etc.). */\n fetchInit?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'>;\n /** Per-request headers merged with (and overriding) global client headers. */\n headers?: Record<string, string>;\n /** External abort signal merged with internal cancellation. */\n signal?: AbortSignal;\n};\n\nexport function buildUrl(base: string, path: string, params?: Params, query?: Params): string {\n const baseClean = base.replace(/\\/+$/, '');\n let pathClean = path.replace(/^\\/+/, '');\n\n pathClean = pathClean.replace(/\\{([^}]+)\\}/g, (_, key: string) => {\n const val = params?.[key];\n\n if (val === undefined || val === null) throw new CourierParseError(`unresolved path param {${key}} in '${path}'`);\n\n return encodeURIComponent(String(val));\n });\n\n const url = baseClean && pathClean ? `${baseClean}/${pathClean}` : baseClean || pathClean;\n\n if (!query) return url;\n\n const qs = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n if (entry !== undefined) {\n qs.append(key, entry === null ? '' : String(entry));\n }\n }\n\n continue;\n }\n\n qs.append(key, value === null ? '' : String(value));\n }\n\n const queryString = qs.toString();\n\n return queryString ? `${url}${url.includes('?') ? '&' : '?'}${queryString}` : url;\n}\n","import { CourierDisposedError, CourierHttpError, CourierParseError, classifyRequestError } from './errors';\nimport { buildRequestInit } from './serialize';\nimport { anySignal, buildTimeoutSignal, type TransportCore } from './transport';\nimport type { HttpRequestConfig, Params } from './url';\nimport { buildUrl } from './url';\n\nexport type StreamOptions<P extends string = string> = Omit<HttpRequestConfig<P>, 'responseType' | 'schema'> & {\n method?: string;\n};\n\n/** Runtime config without PathConfig's type-level constraints — open() just forwards params to buildUrl. */\ntype StreamRuntimeConfig = {\n body?: unknown;\n fetchInit?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'>;\n headers?: Record<string, string>;\n method?: string;\n params?: Params;\n query?: Params;\n signal?: AbortSignal;\n timeout?: number;\n};\n\nexport type StreamEvent<T = unknown> = { readonly data: T; readonly event: string };\n\nfunction abortable<T>(create: (signal: AbortSignal) => AsyncGenerator<T>): AsyncIterableIterator<T> {\n const controller = new AbortController();\n const iterator = create(controller.signal);\n\n return {\n next: (value?: undefined) => iterator.next(value),\n return: (value?: T) => {\n controller.abort();\n\n return iterator.return(value as T);\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n throw: (error?: unknown) => {\n controller.abort();\n\n return iterator.throw(error);\n },\n };\n}\n\nasync function open(\n transport: TransportCore,\n url: string,\n config: StreamRuntimeConfig,\n): Promise<{ controller: AbortController; response: Response; untrack: () => void }> {\n if (transport.disposed) throw new CourierDisposedError('Courier');\n\n const controller = new AbortController();\n const untrack = transport.track(controller);\n const method = (config.method ?? (config.body === undefined ? 'GET' : 'POST')).toUpperCase();\n const signal = buildTimeoutSignal(\n config.timeout ?? Number.POSITIVE_INFINITY,\n anySignal(config.signal, controller.signal),\n );\n let fullUrl = url;\n\n try {\n fullUrl = buildUrl(transport.baseUrl, url, config.params, config.query);\n\n const headers = transport.mergeHeaders(config.headers);\n const { headers: requestHeaders, ...init } = buildRequestInit(\n method,\n headers,\n config.body,\n signal,\n config.fetchInit ?? {},\n );\n const response = await transport.dispatch({\n headers: requestHeaders as Record<string, string>,\n init,\n url: fullUrl,\n });\n\n if (!response.ok)\n throw CourierHttpError.fromResponse(response, await response.text().catch(() => ''), method, fullUrl);\n\n if (!response.body) throw new CourierParseError('Response has no body');\n\n return { controller, response, untrack };\n } catch (error) {\n untrack();\n\n if (error instanceof CourierHttpError || error instanceof CourierParseError) throw error;\n\n throw classifyRequestError(error, method, fullUrl, signal);\n }\n}\n\n/** Platform-shaped streaming primitives: async iteration owns cancellation and backpressure. */\nexport function createStreams(transport: TransportCore) {\n async function* events<T = unknown, P extends string = string>(\n url: P,\n config: StreamOptions<P>,\n ): AsyncGenerator<StreamEvent<T>> {\n const { controller, response, untrack } = await open(transport, url, config as StreamRuntimeConfig);\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let event = 'message';\n let data = '';\n\n try {\n while (true) {\n const chunk = await reader.read();\n\n if (chunk.done) break;\n\n buffer += decoder.decode(chunk.value, { stream: true }).replace(/\\r\\n?/g, '\\n');\n\n let newline: number;\n\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline);\n\n buffer = buffer.slice(newline + 1);\n\n if (line === '') {\n if (data !== '') {\n let parsed: unknown = data.endsWith('\\n') ? data.slice(0, -1) : data;\n\n try {\n parsed = JSON.parse(parsed as string);\n } catch {\n // SSE text payloads are valid raw values.\n }\n\n yield { data: parsed as T, event };\n }\n\n data = '';\n event = 'message';\n continue;\n }\n\n if (line.startsWith(':')) continue;\n\n const separator = line.indexOf(':');\n const field = separator === -1 ? line : line.slice(0, separator);\n const value = (separator === -1 ? '' : line.slice(separator + 1)).replace(/^ /, '');\n\n if (field === 'data') data += `${value}\\n`;\n else if (field === 'event') event = value;\n }\n }\n } finally {\n reader.releaseLock();\n controller.abort();\n untrack();\n }\n }\n\n async function* read<T = string, P extends string = string>(\n url: P,\n config: StreamOptions<P> & { parse?: 'ndjson' | 'text' },\n ): AsyncGenerator<T> {\n const { controller, response, untrack } = await open(transport, url, config as StreamRuntimeConfig);\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const chunk = await reader.read();\n\n if (chunk.done) {\n if (config.parse === 'ndjson' && buffer.trim()) {\n try {\n yield JSON.parse(buffer) as T;\n } catch {\n throw new CourierParseError(`NDJSON: failed to parse line: ${buffer.slice(0, 200)}`);\n }\n }\n\n break;\n }\n\n const text = decoder.decode(chunk.value, { stream: true });\n\n if (config.parse !== 'ndjson') {\n yield text as T;\n continue;\n }\n\n buffer += text;\n\n let newline: number;\n\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline).trim();\n\n buffer = buffer.slice(newline + 1);\n\n if (!line) continue;\n\n try {\n yield JSON.parse(line) as T;\n } catch {\n throw new CourierParseError(`NDJSON: failed to parse line: ${line.slice(0, 200)}`);\n }\n }\n }\n } finally {\n reader.releaseLock();\n controller.abort();\n untrack();\n }\n }\n\n return {\n events<T = unknown, P extends string = string>(\n url: P,\n config: StreamOptions<P> = {} as StreamOptions<P>,\n ): AsyncIterableIterator<StreamEvent<T>> {\n return abortable((signal) =>\n events<T, P>(url, {\n ...config,\n headers: { accept: 'text/event-stream', 'cache-control': 'no-cache', ...config.headers },\n signal: anySignal(config.signal, signal),\n }),\n );\n },\n read<T = string, P extends string = string>(\n url: P,\n config: StreamOptions<P> & { parse?: 'ndjson' | 'text' } = {} as StreamOptions<P> & {\n parse?: 'ndjson' | 'text';\n },\n ): AsyncIterableIterator<T> {\n return abortable((signal) => read<T, P>(url, { ...config, signal: anySignal(config.signal, signal) }));\n },\n };\n}\n","import { CourierDisposedError, CourierHttpError, CourierSchemaValidationError, classifyRequestError } from './errors';\nimport { createQueryCache } from './query';\nimport { parseResponse } from './response';\nimport { buildRequestInit } from './serialize';\nimport { createStreams } from './stream';\nimport {\n anySignal,\n buildTimeoutSignal,\n createTransportCore,\n type TransportOptions,\n validateTimeout,\n} from './transport';\nimport type { MutationOptions, QueryCache } from './types';\nimport type { HttpRequestConfig, Params } from './url';\nimport { buildUrl } from './url';\n\nexport type CourierOptions = TransportOptions & {\n query?: { gcTime?: number; staleTime?: number };\n};\n\nexport type Courier = ReturnType<typeof createCourier>;\n\n/** One application client owns transport, queries, mutations, and streams. */\nexport function createCourier(options: CourierOptions = {}) {\n const { query: queryOptions, ...transportOptions } = options;\n const transport = createTransportCore(transportOptions);\n const queryCache = createQueryCache({ ...queryOptions, signal: transport.disposalSignal });\n const queries: QueryCache = queryCache;\n const streams = createStreams(transport);\n const mutations = new Set<AbortController>();\n\n async function execute<T>(\n headers: Record<string, string>,\n init: Omit<RequestInit, 'headers'>,\n full: string,\n m: string,\n responseType: HttpRequestConfig['responseType'],\n schema?: { parse(data: unknown): T },\n ): Promise<T> {\n const signal = init.signal as AbortSignal | undefined;\n let res: Response;\n\n try {\n res = await transport.dispatch({ headers, init, url: full });\n } catch (err) {\n throw classifyRequestError(err, m, full, signal);\n }\n\n if (!res.ok) {\n // Error bodies are read once as text, then JSON-parsed if the content-type\n // says so — a binary success config (`responseType: 'blob'`) must not trap\n // the server's error message in an unreadable wrapper, and a failed\n // parseResponse-then-fallback double-read loses the body entirely.\n const isJson = res.headers.get('content-type')?.includes('json') ?? false;\n const text = await res.text().catch(() => '');\n let body: unknown = text;\n\n if (text && isJson) {\n try {\n body = JSON.parse(text);\n } catch {\n // Malformed JSON error body — keep the raw text, not ''.\n }\n }\n\n throw CourierHttpError.fromResponse(res, body, m, full);\n }\n\n let raw: unknown;\n\n try {\n raw = await parseResponse(res, responseType ?? 'auto');\n } catch (err) {\n throw classifyRequestError(err, m, full, signal);\n }\n\n if (schema) {\n try {\n return schema.parse(raw);\n } catch (err) {\n throw new CourierSchemaValidationError(err, raw);\n }\n }\n\n return raw as T;\n }\n\n async function request<T, P extends string = string>(\n method: string,\n url: P,\n config: HttpRequestConfig<P> = {} as HttpRequestConfig<P>,\n ) {\n if (transport.disposed) throw new CourierDisposedError('Courier');\n\n const m = method.toUpperCase();\n\n let full: string;\n\n try {\n full = buildUrl(transport.baseUrl, url, config.params as Params | undefined, config.query);\n } catch (err) {\n throw classifyRequestError(err, m, url);\n }\n\n const {\n body,\n fetchInit,\n headers,\n responseType,\n schema,\n signal: extSignal,\n timeout: cfgTimeout,\n } = config as HttpRequestConfig;\n\n if (cfgTimeout !== undefined) validateTimeout(cfgTimeout);\n\n const requestAc = new AbortController();\n const untrack = transport.track(requestAc);\n const signal = buildTimeoutSignal(cfgTimeout ?? transport.getTimeout(), anySignal(extSignal, requestAc.signal));\n const { headers: initHeaders, ...restInit } = buildRequestInit(\n m,\n transport.mergeHeaders(headers),\n body,\n signal,\n fetchInit ?? {},\n );\n\n try {\n return await execute<T>(\n initHeaders as Record<string, string>,\n restInit,\n full,\n m,\n responseType,\n schema as { parse(data: unknown): T } | undefined,\n );\n } finally {\n untrack();\n }\n }\n\n const mutate = async <T>(options: MutationOptions<T>): Promise<T> => {\n if (transport.disposed) throw new CourierDisposedError('Courier');\n\n const controller = new AbortController();\n\n mutations.add(controller);\n\n const signal = anySignal(options.signal, controller.signal, transport.disposalSignal) ?? controller.signal;\n\n try {\n const data = await options.request({ signal });\n\n await options.onSuccess?.(data, queries);\n\n for (const key of options.invalidateKeys ?? []) {\n queries.invalidate(key, { refetch: true });\n }\n\n return data;\n } finally {\n mutations.delete(controller);\n }\n };\n\n return {\n cancelAll() {\n transport.cancelAll();\n queryCache.cancelAll();\n for (const controller of mutations) controller.abort();\n },\n delete: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('DELETE', url, cfg),\n get disposalSignal() {\n return transport.disposalSignal;\n },\n dispose() {\n for (const controller of mutations) controller.abort();\n mutations.clear();\n queries.clear();\n transport.dispose();\n },\n get disposed() {\n return transport.disposed;\n },\n events: streams.events,\n get: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('GET', url, cfg),\n getHeaders: transport.getHeaders,\n mutate,\n patch: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('PATCH', url, cfg),\n post: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('POST', url, cfg),\n put: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('PUT', url, cfg),\n queries,\n read: streams.read,\n setHeaders: transport.setHeaders,\n [Symbol.dispose]() {\n this.dispose();\n },\n use: transport.use,\n };\n}\n","//#region src/random/uuid.ts\nfunction e() {\n\treturn crypto.randomUUID();\n}\n//#endregion\nexport { e as uuid };\n\n//# sourceMappingURL=uuid.js.map","import { uuid } from '@vielzeug/arsenal/random';\n\nimport type { Interceptor } from './transport';\n\n/**\n * Attaches a Bearer token `Authorization` header to every request.\n * The token can be a static string or an async function (useful for refresh flows).\n *\n * @example\n * ```ts\n * client.use(withBearerAuth(() => tokenStore.getAccessToken()));\n * ```\n */\nexport function withBearerAuth(token: string | (() => string | Promise<string>)): Interceptor {\n return async (ctx, next) => {\n const t = typeof token === 'function' ? await token() : token;\n\n return next(ctx.withHeaders({ authorization: `Bearer ${t}` }));\n };\n}\n\n/**\n * Adds a unique request ID to every request as a header.\n *\n * Defaults to `x-request-id` populated with `crypto.randomUUID()`.\n *\n * @example\n * ```ts\n * client.use(withRequestId());\n * client.use(withRequestId({ header: 'x-trace-id' }));\n * ```\n */\nexport function withRequestId(opts?: { generate?: () => string; header?: string }): Interceptor {\n const header = opts?.header ?? 'x-request-id';\n const generate = opts?.generate ?? uuid;\n\n return (ctx, next) => next(ctx.withHeaders({ [header]: generate() }));\n}\n\n/**\n * Logs each request's method, URL, status code, and duration.\n *\n * Requires an explicit `logger` function — no default console output.\n *\n * **Security note:** The full URL is logged, including any query parameters.\n * If your URLs may contain sensitive data (tokens, PII), provide a custom\n * `logger` that sanitizes the URL before writing to persistent logs.\n *\n * @example\n * ```ts\n * client.use(withLogging({ logger: (msg) => console.log(msg) }));\n * client.use(withLogging({ logger: (msg, meta) => logger.info(meta) }));\n * ```\n */\nexport function withLogging(opts: {\n logger: (msg: string, meta: { duration: number; method: string; status: number; url: string }) => void;\n}): Interceptor {\n const log = opts.logger;\n\n return async (ctx, next) => {\n const start = performance.now();\n const method = ((ctx.init as RequestInit).method ?? 'GET').toUpperCase();\n\n try {\n const res = await next(ctx);\n const duration = Math.round(performance.now() - start);\n\n log(`${method} ${ctx.url} ${res.status} (${duration}ms)`, {\n duration,\n method,\n status: res.status,\n url: ctx.url,\n });\n\n return res;\n } catch (err) {\n const duration = Math.round(performance.now() - start);\n\n log(`${method} ${ctx.url} ERR (${duration}ms)`, {\n duration,\n method,\n status: 0,\n url: ctx.url,\n });\n\n throw err;\n }\n };\n}\n"],"mappings":"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"}
package/dist/courier.d.ts CHANGED
@@ -3,6 +3,7 @@ import type { MutationOptions, QueryCache } from './types';
3
3
  import type { HttpRequestConfig } from './url';
4
4
  export type CourierOptions = TransportOptions & {
5
5
  query?: {
6
+ gcTime?: number;
6
7
  staleTime?: number;
7
8
  };
8
9
  };
@@ -17,7 +18,6 @@ export declare function createCourier(options?: CourierOptions): {
17
18
  events: <T = unknown, P extends string = string>(url: P, config?: import("./stream").StreamOptions<P>) => AsyncIterableIterator<import("./stream").StreamEvent<T>>;
18
19
  get: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => Promise<T>;
19
20
  getHeaders: () => Readonly<Record<string, string>>;
20
- headers: (updates: Record<string, string | undefined>) => void;
21
21
  mutate: <T>(options: MutationOptions<T>) => Promise<T>;
22
22
  patch: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => Promise<T>;
23
23
  post: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => Promise<T>;
@@ -26,7 +26,7 @@ export declare function createCourier(options?: CourierOptions): {
26
26
  read: <T = string, P extends string = string>(url: P, config?: import("./stream").StreamOptions<P> & {
27
27
  parse?: "ndjson" | "text";
28
28
  }) => AsyncIterableIterator<T>;
29
- request: <T, P extends string = string>(method: string, url: P, config?: HttpRequestConfig<P>) => Promise<T>;
29
+ setHeaders: (updates: Record<string, string | undefined>) => void;
30
30
  [Symbol.dispose](): void;
31
31
  use: (interceptor: import("./transport").Interceptor) => () => void;
32
32
  };
@@ -1 +1 @@
1
- {"version":3,"file":"courier.d.ts","sourceRoot":"","sources":["../src/courier.ts"],"names":[],"mappings":"AAKA,OAAO,EAIL,KAAK,gBAAgB,EAEtB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAU,MAAM,OAAO,CAAC;AAGvD,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG;IAC9C,KAAK,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAEvD,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,OAAO,GAAE,cAAmB;;aAgJ7C,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;;;;;UAcnE,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;;;aAxClD,CAAC,WAAW,eAAe,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAAC;YA4CvD,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;WACjE,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;UACjE,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;;;aAUsnB,CAAC;;cA9GxqB,CAAC,EAAE,CAAC,SAAS,MAAM,mBAChC,MAAM,OACT,CAAC,WACE,iBAAiB,CAAC,CAAC,CAAC;;;EA0G/B"}
1
+ {"version":3,"file":"courier.d.ts","sourceRoot":"","sources":["../src/courier.ts"],"names":[],"mappings":"AAKA,OAAO,EAIL,KAAK,gBAAgB,EAEtB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAU,MAAM,OAAO,CAAC;AAGvD,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG;IAC9C,KAAK,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAEvD,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,OAAO,GAAE,cAAmB;;aAoJ7C,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;;;;;UAcnE,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;;aA5ClD,CAAC,WAAW,eAAe,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAAC;YA+CvD,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;WACjE,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;UACjE,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;;;aAUutB,CAAC;;;;;EADjyB"}
@@ -1,6 +1,6 @@
1
- var Courier=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},n=class e extends t{url;method;status;data;headers;constructor(e){super(e.message),this.url=e.url,this.method=e.method,this.status=e.status,this.data=e.data,this.headers=e.headers}static fromResponse(t,n,r,i){return new e({data:n,headers:t.headers,message:t.statusText||`HTTP ${t.status}`,method:r,status:t.status,url:i})}static is(t,n){return t instanceof e&&(n===void 0||t.status===n)}},r=class extends t{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},i=class extends t{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},a=class extends t{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},o=class extends t{data;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.data=t}},s=class extends t{constructor(e){super(`[courier] ${e} disposed`)}},c=class extends t{};function l(e,t,n,o){let s=e instanceof Error?e.message:String(e),c=o?.reason;return c instanceof Error&&c.name===`TimeoutError`?new i({cause:e,message:s,method:t,url:n}):e instanceof DOMException?e.name===`TimeoutError`?new i({cause:e,message:s,method:t,url:n}):new a({cause:e,message:s,method:t,url:n}):e instanceof Error&&e.name===`AbortError`||o?.aborted?new a({cause:e,message:s,method:t,url:n}):new r({cause:e,message:s,method:t,url:n})}var u=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},d=class extends u{};function f(e,t,n){if(e===void 0)return`undefined`;if(e===null)return`null`;if(typeof e==`bigint`)return`${e}n`;if(typeof e!=`object`)return JSON.stringify(e);if(n.has(e))return`[Circular]`;if(n.add(e),e instanceof Date)return`[Date:${Number.isNaN(e.getTime())?`Invalid`:e.toISOString()}]`;if(e instanceof RegExp)return`[RegExp:${e.source}/${e.flags}]`;if(e instanceof Set)return`[Set:${[...e].map(e=>f(e,t,n)).sort().join(`,`)}]`;if(e instanceof Map)return`[Map:${[...e.entries()].map(([e,r])=>[f(e,t,n),f(r,t,n)]).sort(([e,t],[n,r])=>e===n?t.localeCompare(r):e.localeCompare(n)).map(([e,t])=>`${e}=>${t}`).join(`,`)}]`;if(Array.isArray(e))return`[${e.map(e=>f(e,t,n)).join(`,`)}]`;let r=Object.getPrototypeOf(e);if(r!==Object.prototype&&r!==null){if(t?.onClassInstance===`throw`)throw new d(`hash: unsupported type ${e.constructor?.name??`unknown`}`);return String(e)}let i=e;return`{${Object.keys(i).filter(e=>i[e]!==void 0).sort().map(e=>`${JSON.stringify(e)}:${f(i[e],t,n)}`).join(`,`)}}`}function p(e,t){return f(e,t,new Set)}function m(e,t,n,r,i){return n!==void 0&&!h(n)?{...i,body:JSON.stringify(n),headers:{"content-type":`application/json`,...t},method:e.toUpperCase(),signal:r}:{...i,...n!==void 0&&{body:n},headers:t,method:e.toUpperCase(),signal:r}}function h(e){return e instanceof FormData||e instanceof Blob||e instanceof URLSearchParams||typeof e==`string`||e instanceof ArrayBuffer||ArrayBuffer.isView(e)||typeof ReadableStream<`u`&&e instanceof ReadableStream}var g=0;function _(e=!1){return{data:void 0,error:null,isFetching:e,status:`loading`,updatedAt:void 0}}function v(e){let t=new Map,n=new Map,r=e?.signal?.aborted??!1,i=e=>{for(let t of[...n.get(p(e))??[]])t()},a=()=>{for(let e of t.values())e.controller?.abort()},o=()=>{let e=[...t.values()].map(e=>e.key);a(),t.clear();for(let t of e)i(t)};e?.signal?.addEventListener(`abort`,()=>{r=!0,o()},{once:!0});let c=e=>{let n=p(e),r=t.get(n);return r||(r={controller:void 0,definition:void 0,key:e,promise:void 0,snapshot:_()},t.set(n,r)),r},l=(t,n)=>{if(r)return Promise.reject(new s(`QueryCache`));if(!t.definition)return Promise.reject(Error(`No fetch function registered for query ${p(t.key)}.`));let a=t.definition.staleTime??e?.staleTime??g;if(!n&&t.snapshot.status===`success`&&Date.now()-t.snapshot.updatedAt<a&&!t.snapshot.isFetching)return Promise.resolve(t.snapshot.data);if(t.promise)return t.promise;let o=new AbortController;t.controller=o,t.snapshot=t.snapshot.status===`success`?{...t.snapshot,isFetching:!0}:{..._(!0)},i(t.key);let c=Promise.resolve().then(()=>t.definition?.fetch({key:t.key,signal:o.signal})).then(e=>(t.snapshot={data:e,error:null,isFetching:!1,status:`success`,updatedAt:Date.now()},t.controller=void 0,t.promise=void 0,i(t.key),e),e=>{let n=e instanceof Error?e:Error(String(e));throw t.snapshot={data:t.snapshot.status===`success`?t.snapshot.data:void 0,error:n,isFetching:!1,status:`error`,updatedAt:Date.now()},t.controller=void 0,t.promise=void 0,i(t.key),n});return t.promise=c,c};return{cancelAll:a,clear:o,fetch(e,t){let n=c(e.key);return n.definition=e,l(n,t?.force??!1)},get(e){let n=t.get(p(e));return n?.snapshot.status===`success`?n.snapshot.data:void 0},getSnapshot(e){return t.get(p(e))?.snapshot??null},invalidate(e){for(let n of t.values())e.length<=n.key.length&&e.every((e,t)=>p(e)===p(n.key[t]))&&(n.snapshot.status===`success`&&(n.snapshot={...n.snapshot,updatedAt:0}),i(n.key))},keys(){return[...t.values()].map(e=>e.key)},refetchStale(){for(let n of t.values()){if(!n.definition||n.snapshot.status!==`success`||n.snapshot.isFetching)continue;let t=n.definition.staleTime??e?.staleTime??g;Date.now()-n.snapshot.updatedAt>=t&&l(n,!0).catch(()=>{`${p(n.key)}`})}},set(e,t,n){let r=c(e);r.snapshot={data:t,error:null,isFetching:!1,status:`success`,updatedAt:n?.updatedAt??Date.now()},i(e)},subscribe(e,t){let r=p(e),i=n.get(r)??new Set;return i.add(t),n.set(r,i),()=>{i.delete(t),i.size===0&&n.delete(r)}}}}async function y(e,t=`auto`){if(t===`raw`)return e;if(e.status===204||e.status===205||e.status===304)return;if(t===`json`)return e.json();if(t===`text`)return e.text();if(t===`blob`)return e.blob();if(t===`arrayBuffer`)return e.arrayBuffer();let n=e.headers.get(`content-type`)??``;return n.includes(`application/json`)||n.includes(`+json`)?e.json():n.startsWith(`text/`)?e.text():n.startsWith(`image/`)||n.startsWith(`audio/`)||n.startsWith(`video/`)?e.blob():e.text()}function b(e,t,n){return{headers:t,init:n,url:e,withHeaders(r){let i={...t};for(let[e,t]of Object.entries(r))i[e.toLowerCase()]=t;return b(e,i,n)}}}function x(...e){let t=e.filter(e=>e!=null);if(t.length!==0)return t.length===1?t[0]:AbortSignal.any(t)}var S=3e4;function C(e){if((e<=0||!Number.isFinite(e))&&e!==1/0)throw new t(`[courier] timeout must be a positive number or Infinity`)}function w(e,t){return e===1/0?t??void 0:x(AbortSignal.timeout(e),t)}function T(e={}){let{baseUrl:t=``,fetch:n=globalThis.fetch,headers:r={},timeout:i=S}=e;C(i);let a=Object.fromEntries(Object.entries(r).map(([e,t])=>[e.toLowerCase(),t])),o=new Set,s=new AbortController,c=[],l=null,u=!1;function d(){if(l)return l;let e=e=>n(e.url,{...e.init,headers:e.headers});return l=c.length===0?e:c.reduceRight((e,t)=>n=>t(n,e),e),l}function f(e){return c.push(e),l=null,()=>{let t=c.indexOf(e);t!==-1&&(c.splice(t,1),l=null)}}function p(e){for(let[t,n]of Object.entries(e)){let e=t.toLowerCase();n===void 0?delete a[e]:a[e]=n}}function m(){return{...a}}function h(e,t){let n=e?Object.fromEntries(Object.entries(e).map(([e,t])=>[e.toLowerCase(),t])):void 0;return{...a,...n,...t}}function g(e){return o.add(e),()=>o.delete(e)}function _(e){return d()(b(e.url,e.headers,e.init))}function v(){for(let e of[...o])e.abort();o.clear()}function y(){if(!u){u=!0,s.abort();for(let e of o)e.abort();o.clear(),c.length=0,l=null}}return{baseUrl:t,cancelAll:v,dispatch:_,get disposalSignal(){return s.signal},dispose:y,get disposed(){return u},getHeaders:m,getTimeout(){return i},headers:p,mergeHeaders:h,track:g,use:f}}function E(e,t,n,r){let i=e.replace(/\/+$/,``),a=t.replace(/^\/+/,``);a=a.replace(/\{([^}]+)\}/g,(e,r)=>{let i=n?.[r];if(i==null)throw new c(`unresolved path param {${r}} in '${t}'`);return encodeURIComponent(String(i))});let o=i&&a?`${i}/${a}`:i||a;if(!r)return o;let s=new URLSearchParams;for(let[e,t]of Object.entries(r))if(t!==void 0){if(Array.isArray(t)){for(let n of t)n!==void 0&&s.append(e,n===null?``:String(n));continue}s.append(e,t===null?``:String(t))}let l=s.toString();return l?`${o}${o.includes(`?`)?`&`:`?`}${l}`:o}function D(e){let t=new AbortController,n=e(t.signal);return{next:e=>n.next(e),return:e=>(t.abort(),n.return(e)),[Symbol.asyncIterator](){return this},throw:e=>(t.abort(),n.throw(e))}}async function O(e,t,r){if(e.disposed)throw new s(`Courier`);let i=new AbortController,a=e.track(i),o=(r.method??(r.body===void 0?`GET`:`POST`)).toUpperCase(),u=w(r.timeout??1/0,x(r.signal,i.signal)),d=t;try{d=E(e.baseUrl,t,r.params,r.query);let{headers:s,...l}=m(o,e.mergeHeaders(r.headers),r.body,u,r.fetchInit??{}),f=await e.dispatch({headers:s,init:l,url:d});if(!f.ok)throw n.fromResponse(f,await f.text().catch(()=>``),o,d);if(!f.body)throw new c(`Response has no body`);return{controller:i,response:f,untrack:a}}catch(e){throw a(),e instanceof n||e instanceof c?e:l(e,o,d,u)}}function k(e){async function*t(t,n){let{controller:r,response:i,untrack:a}=await O(e,t,n),o=i.body.getReader(),s=new TextDecoder,c=``,l=`message`,u=``;try{for(;;){let e=await o.read();if(e.done)break;c+=s.decode(e.value,{stream:!0}).replace(/\r\n?/g,`
1
+ var Courier=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},n=class e extends t{url;method;status;data;headers;constructor(e){super(e.message),this.url=e.url,this.method=e.method,this.status=e.status,this.data=e.data,this.headers=e.headers}static fromResponse(t,n,r,i){return new e({data:n,headers:t.headers,message:t.statusText||`HTTP ${t.status}`,method:r,status:t.status,url:i})}static is(t,n){return t instanceof e&&(n===void 0||t.status===n)}},r=class extends t{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},i=class extends t{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},a=class extends t{url;method;constructor(e){super(e.message,{cause:e.cause}),this.url=e.url,this.method=e.method}},o=class extends t{data;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.data=t}},s=class extends t{constructor(e){super(`[courier] ${e} disposed`)}},c=class extends t{};function l(e,t,n,o){let s=e instanceof Error?e.message:String(e),c=o?.reason;return c instanceof Error&&c.name===`TimeoutError`?new i({cause:e,message:s,method:t,url:n}):e instanceof DOMException?e.name===`TimeoutError`?new i({cause:e,message:s,method:t,url:n}):new a({cause:e,message:s,method:t,url:n}):e instanceof Error&&e.name===`AbortError`||o?.aborted?new a({cause:e,message:s,method:t,url:n}):new r({cause:e,message:s,method:t,url:n})}var u=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},d=class extends u{};function f(e,t,n){if(e===void 0)return`undefined`;if(e===null)return`null`;if(typeof e==`bigint`)return`${e}n`;if(typeof e!=`object`)return JSON.stringify(e);if(n.has(e))return`[Circular]`;if(n.add(e),e instanceof Date)return`[Date:${Number.isNaN(e.getTime())?`Invalid`:e.toISOString()}]`;if(e instanceof RegExp)return`[RegExp:${e.source}/${e.flags}]`;if(e instanceof Set)return`[Set:${[...e].map(e=>f(e,t,n)).sort().join(`,`)}]`;if(e instanceof Map)return`[Map:${[...e.entries()].map(([e,r])=>[f(e,t,n),f(r,t,n)]).sort(([e,t],[n,r])=>e===n?t.localeCompare(r):e.localeCompare(n)).map(([e,t])=>`${e}=>${t}`).join(`,`)}]`;if(Array.isArray(e))return`[${e.map(e=>f(e,t,n)).join(`,`)}]`;let r=Object.getPrototypeOf(e);if(r!==Object.prototype&&r!==null){if(t?.onClassInstance===`throw`)throw new d(`hash: unsupported type ${e.constructor?.name??`unknown`}`);return String(e)}let i=e;return`{${Object.keys(i).filter(e=>i[e]!==void 0).sort().map(e=>`${JSON.stringify(e)}:${f(i[e],t,n)}`).join(`,`)}}`}function p(e,t){return f(e,t,new Set)}var m=0,h=3e5;function g(e=!1){return{data:void 0,error:null,isFetching:e,status:`loading`,updatedAt:void 0}}function _(e){let t=e?.staleTime??m,n=e?.gcTime??h,r=new Map,i=new Map,a=e?.signal?.aborted??!1,o,c=e=>(i.get(e)?.size??0)>0,l=e=>{for(let t of[...i.get(p(e))??[]])t()},u=()=>{if(n===1/0||a){o&&clearTimeout(o),o=void 0;return}o&&clearTimeout(o);let e;for(let t of r.values()){if(t.snapshot.status!==`success`||t.promise||c(p(t.key)))continue;let r=t.snapshot.updatedAt+n;(e===void 0||r<e)&&(e=r)}if(e===void 0){o=void 0;return}o=setTimeout(d,Math.max(0,e-Date.now()))},d=()=>{let e=Date.now();for(let[t,i]of r)i.snapshot.status!==`success`||i.promise||c(t)||e-i.snapshot.updatedAt>=n&&r.delete(t);u()},f=()=>{for(let e of r.values())e.controller?.abort()},_=()=>{let e=[...r.values()].map(e=>e.key);f(),r.clear(),o&&=(clearTimeout(o),void 0);for(let t of e)l(t)};e?.signal?.addEventListener(`abort`,()=>{a=!0,_()},{once:!0});let v=e=>{let t=p(e),n=r.get(t);return n||(n={controller:void 0,definition:void 0,key:e,promise:void 0,snapshot:g()},r.set(t,n)),n},y=(e,n)=>{if(a)return Promise.reject(new s(`QueryCache`));if(!e.definition)return Promise.reject(Error(`No fetch function registered for query ${p(e.key)}.`));let r=e.definition.staleTime??t;if(!n&&e.snapshot.status===`success`&&Date.now()-e.snapshot.updatedAt<r&&!e.snapshot.isFetching)return Promise.resolve(e.snapshot.data);if(e.promise)return e.promise;let i=new AbortController;e.controller=i,e.snapshot=e.snapshot.status===`success`?{...e.snapshot,isFetching:!0}:{...g(!0)},l(e.key);let o=Promise.resolve().then(()=>e.definition?.fetch({key:e.key,signal:i.signal})).then(t=>(e.snapshot={data:t,error:null,isFetching:!1,status:`success`,updatedAt:Date.now()},e.controller=void 0,e.promise=void 0,l(e.key),u(),t),t=>{let n=t instanceof Error?t:Error(String(t));throw e.snapshot={data:e.snapshot.status===`success`?e.snapshot.data:void 0,error:n,isFetching:!1,status:`error`,updatedAt:Date.now()},e.controller=void 0,e.promise=void 0,l(e.key),n});return e.promise=o,o};return{cancelAll:f,clear:_,fetch(e,t){let n=v(e.key);return n.definition=e,y(n,t?.force??!1)},get(e){let t=r.get(p(e));return t?.snapshot.status===`success`?t.snapshot.data:void 0},getSnapshot(e){return r.get(p(e))?.snapshot??null},invalidate(e,t){let n=t?.refetch??!1,i=!1;for(let t of r.values())e.length<=t.key.length&&e.every((e,n)=>e===t.key[n])&&(t.snapshot.status===`success`&&(t.snapshot={...t.snapshot,updatedAt:0}),l(t.key),n&&t.definition&&!t.promise&&y(t,!0).catch(()=>{}),i=!0);i&&u()},keys(){return[...r.values()].map(e=>e.key)},set(e,t,n){let r=v(e);r.snapshot={data:t,error:null,isFetching:!1,status:`success`,updatedAt:n?.updatedAt??Date.now()},l(e),u()},subscribe(e,t){let n=p(e),r=i.get(n)??new Set;return r.add(t),i.set(n,r),()=>{r.delete(t),r.size===0&&(i.delete(n),u())}}}}async function v(e){let t=(await e.text()).trim();return t?JSON.parse(t):void 0}async function y(e,t=`auto`){if(t===`raw`)return e;if(e.status===204||e.status===205||e.status===304)return;if(t===`json`)return v(e);if(t===`text`)return e.text();if(t===`blob`)return e.blob();if(t===`arrayBuffer`)return e.arrayBuffer();let n=e.headers.get(`content-type`)??``;return n.includes(`application/json`)||n.includes(`+json`)?v(e):n.startsWith(`text/`)?e.text():n.startsWith(`image/`)||n.startsWith(`audio/`)||n.startsWith(`video/`)?e.blob():e.text()}function b(e,t,n,r,i){return n!==void 0&&!x(n)?{...i,body:JSON.stringify(n),headers:{"content-type":`application/json`,...t},method:e.toUpperCase(),signal:r}:{...i,...n!==void 0&&{body:n},headers:t,method:e.toUpperCase(),signal:r}}function x(e){return e instanceof FormData||e instanceof Blob||e instanceof URLSearchParams||typeof e==`string`||e instanceof ArrayBuffer||ArrayBuffer.isView(e)||typeof ReadableStream<`u`&&e instanceof ReadableStream}function S(e,t,n){return{headers:t,init:n,url:e,withHeaders(r){let i={...t};for(let[e,t]of Object.entries(r))i[e.toLowerCase()]=t;return S(e,i,n)}}}function C(...e){let t=e.filter(e=>e!=null);if(t.length!==0)return t.length===1?t[0]:AbortSignal.any(t)}var w=3e4;function T(e){if((e<=0||!Number.isFinite(e))&&e!==1/0)throw new t(`[courier] timeout must be a positive number or Infinity`)}function E(e,t){return e===1/0?t??void 0:C(AbortSignal.timeout(e),t)}function D(e={}){let{baseUrl:t=``,fetch:n=globalThis.fetch,headers:r={},timeout:i=w}=e;T(i);let a=Object.fromEntries(Object.entries(r).map(([e,t])=>[e.toLowerCase(),t])),o=new Set,s=new AbortController,c=[],l=null,u=!1;function d(){if(l)return l;let e=e=>n(e.url,{...e.init,headers:e.headers});return l=c.length===0?e:c.reduceRight((e,t)=>n=>t(n,e),e),l}function f(e){return c.push(e),l=null,()=>{let t=c.indexOf(e);t!==-1&&(c.splice(t,1),l=null)}}function p(e){for(let[t,n]of Object.entries(e)){let e=t.toLowerCase();n===void 0?delete a[e]:a[e]=n}}function m(){return{...a}}function h(e,t){let n=e?Object.fromEntries(Object.entries(e).map(([e,t])=>[e.toLowerCase(),t])):void 0;return{...a,...n,...t}}function g(e){return o.add(e),()=>o.delete(e)}function _(e){return d()(S(e.url,e.headers,e.init))}function v(){for(let e of[...o])e.abort();o.clear()}function y(){if(!u){u=!0,s.abort();for(let e of o)e.abort();o.clear(),c.length=0,l=null}}return{baseUrl:t,cancelAll:v,dispatch:_,get disposalSignal(){return s.signal},dispose:y,get disposed(){return u},getHeaders:m,getTimeout(){return i},mergeHeaders:h,setHeaders:p,track:g,use:f}}function O(e,t,n,r){let i=e.replace(/\/+$/,``),a=t.replace(/^\/+/,``);a=a.replace(/\{([^}]+)\}/g,(e,r)=>{let i=n?.[r];if(i==null)throw new c(`unresolved path param {${r}} in '${t}'`);return encodeURIComponent(String(i))});let o=i&&a?`${i}/${a}`:i||a;if(!r)return o;let s=new URLSearchParams;for(let[e,t]of Object.entries(r))if(t!==void 0){if(Array.isArray(t)){for(let n of t)n!==void 0&&s.append(e,n===null?``:String(n));continue}s.append(e,t===null?``:String(t))}let l=s.toString();return l?`${o}${o.includes(`?`)?`&`:`?`}${l}`:o}function k(e){let t=new AbortController,n=e(t.signal);return{next:e=>n.next(e),return:e=>(t.abort(),n.return(e)),[Symbol.asyncIterator](){return this},throw:e=>(t.abort(),n.throw(e))}}async function A(e,t,r){if(e.disposed)throw new s(`Courier`);let i=new AbortController,a=e.track(i),o=(r.method??(r.body===void 0?`GET`:`POST`)).toUpperCase(),u=E(r.timeout??1/0,C(r.signal,i.signal)),d=t;try{d=O(e.baseUrl,t,r.params,r.query);let{headers:s,...l}=b(o,e.mergeHeaders(r.headers),r.body,u,r.fetchInit??{}),f=await e.dispatch({headers:s,init:l,url:d});if(!f.ok)throw n.fromResponse(f,await f.text().catch(()=>``),o,d);if(!f.body)throw new c(`Response has no body`);return{controller:i,response:f,untrack:a}}catch(e){throw a(),e instanceof n||e instanceof c?e:l(e,o,d,u)}}function j(e){async function*t(t,n){let{controller:r,response:i,untrack:a}=await A(e,t,n),o=i.body.getReader(),s=new TextDecoder,c=``,l=`message`,u=``;try{for(;;){let e=await o.read();if(e.done)break;c+=s.decode(e.value,{stream:!0}).replace(/\r\n?/g,`
2
2
  `);let t;for(;(t=c.indexOf(`
3
3
  `))!==-1;){let e=c.slice(0,t);if(c=c.slice(t+1),e===``){if(u!==``){let e=u.endsWith(`
4
- `)?u.slice(0,-1):u;try{e=JSON.parse(e)}catch{}yield{data:e,event:l}}u=``,l=`message`;continue}if(e.startsWith(`:`))continue;let n=e.indexOf(`:`),r=n===-1?e:e.slice(0,n),i=(n===-1?``:e.slice(n+1)).replace(/^ /,``);r===`data`?u+=`${i}\n`:r===`event`&&(l=i)}}}finally{o.releaseLock(),r.abort(),a()}}async function*n(t,n){let{controller:r,response:i,untrack:a}=await O(e,t,n),o=i.body.getReader(),s=new TextDecoder,l=``;try{for(;;){let e=await o.read();if(e.done){if(n.parse===`ndjson`&&l.trim())try{yield JSON.parse(l)}catch{throw new c(`NDJSON: failed to parse line: ${l.slice(0,200)}`)}break}let t=s.decode(e.value,{stream:!0});if(n.parse!==`ndjson`){yield t;continue}l+=t;let r;for(;(r=l.indexOf(`
5
- `))!==-1;){let e=l.slice(0,r).trim();if(l=l.slice(r+1),e)try{yield JSON.parse(e)}catch{throw new c(`NDJSON: failed to parse line: ${e.slice(0,200)}`)}}}}finally{o.releaseLock(),r.abort(),a()}}return{events(e,n={}){return D(r=>t(e,{...n,headers:{accept:`text/event-stream`,"cache-control":`no-cache`,...n.headers},signal:x(n.signal,r)}))},read(e,t={}){return D(r=>n(e,{...t,signal:x(t.signal,r)}))}}}function A(e={}){let{query:t,...r}=e,i=T(r),a=v({...t,signal:i.disposalSignal}),c=a,u=k(i),d=new Set;async function f(e,t,r,a,s,c){let u=t.signal,d;try{d=await i.dispatch({headers:e,init:t,url:r})}catch(e){throw l(e,a,r,u)}if(!d.ok){let e=d.headers.get(`content-type`)?.includes(`json`)??!1,t=await d.text().catch(()=>``),i=t;if(t&&e)try{i=JSON.parse(t)}catch{}throw n.fromResponse(d,i,a,r)}let f;try{f=await y(d,s??`auto`)}catch(e){throw l(e,a,r,u)}if(c)try{return c.parse(f)}catch(e){throw new o(e,f)}return f}async function p(e,t,n={}){if(i.disposed)throw new s(`Courier`);let r=e.toUpperCase(),a;try{a=E(i.baseUrl,t,n.params,n.query)}catch(e){throw l(e,r,t)}let{body:o,fetchInit:c,headers:u,responseType:d,schema:p,signal:h,timeout:g}=n;g!==void 0&&C(g);let _=new AbortController,v=i.track(_),y=w(g??i.getTimeout(),x(h,_.signal)),{headers:b,...S}=m(r,i.mergeHeaders(u),o,y,c??{});try{return await f(b,S,a,r,d,p)}finally{v()}}return{cancelAll(){i.cancelAll(),a.cancelAll();for(let e of d)e.abort()},delete:(e,t)=>p(`DELETE`,e,t),get disposalSignal(){return i.disposalSignal},dispose(){for(let e of d)e.abort();d.clear(),c.clear(),i.dispose()},get disposed(){return i.disposed},events:u.events,get:(e,t)=>p(`GET`,e,t),getHeaders:i.getHeaders,headers:i.headers,mutate:async e=>{if(i.disposed)throw new s(`Courier`);let t=new AbortController;d.add(t);let n=x(e.signal,t.signal,i.disposalSignal)??t.signal;try{let t=await e.request({signal:n});return await e.onSuccess?.(t,c),t}finally{d.delete(t)}},patch:(e,t)=>p(`PATCH`,e,t),post:(e,t)=>p(`POST`,e,t),put:(e,t)=>p(`PUT`,e,t),queries:c,read:u.read,request:p,[Symbol.dispose](){this.dispose()},use:i.use}}function j(){return crypto.randomUUID()}function M(e){return async(t,n)=>{let r=typeof e==`function`?await e():e;return n(t.withHeaders({authorization:`Bearer ${r}`}))}}function N(e){let t=e?.header??`x-request-id`,n=e?.generate??j;return(e,r)=>r(e.withHeaders({[t]:n()}))}function P(e){let t=e?.logger??((e,t)=>{console.debug(e,t)});return async(e,n)=>{let r=performance.now(),i=(e.init.method??`GET`).toUpperCase();try{let a=await n(e),o=Math.round(performance.now()-r);return t(`${i} ${e.url} ${a.status} (${o}ms)`,{duration:o,method:i,status:a.status,url:e.url}),a}catch(n){let a=Math.round(performance.now()-r);throw t(`${i} ${e.url} ERR (${a}ms)`,{duration:a,method:i,status:0,url:e.url}),n}}}return e.CourierAbortError=a,e.CourierDisposedError=s,e.CourierError=t,e.CourierHttpError=n,e.CourierNetworkError=r,e.CourierParseError=c,e.CourierSchemaValidationError=o,e.CourierTimeoutError=i,e.createCourier=A,e.withBearerAuth=M,e.withLogging=P,e.withRequestId=N,e})({});
4
+ `)?u.slice(0,-1):u;try{e=JSON.parse(e)}catch{}yield{data:e,event:l}}u=``,l=`message`;continue}if(e.startsWith(`:`))continue;let n=e.indexOf(`:`),r=n===-1?e:e.slice(0,n),i=(n===-1?``:e.slice(n+1)).replace(/^ /,``);r===`data`?u+=`${i}\n`:r===`event`&&(l=i)}}}finally{o.releaseLock(),r.abort(),a()}}async function*n(t,n){let{controller:r,response:i,untrack:a}=await A(e,t,n),o=i.body.getReader(),s=new TextDecoder,l=``;try{for(;;){let e=await o.read();if(e.done){if(n.parse===`ndjson`&&l.trim())try{yield JSON.parse(l)}catch{throw new c(`NDJSON: failed to parse line: ${l.slice(0,200)}`)}break}let t=s.decode(e.value,{stream:!0});if(n.parse!==`ndjson`){yield t;continue}l+=t;let r;for(;(r=l.indexOf(`
5
+ `))!==-1;){let e=l.slice(0,r).trim();if(l=l.slice(r+1),e)try{yield JSON.parse(e)}catch{throw new c(`NDJSON: failed to parse line: ${e.slice(0,200)}`)}}}}finally{o.releaseLock(),r.abort(),a()}}return{events(e,n={}){return k(r=>t(e,{...n,headers:{accept:`text/event-stream`,"cache-control":`no-cache`,...n.headers},signal:C(n.signal,r)}))},read(e,t={}){return k(r=>n(e,{...t,signal:C(t.signal,r)}))}}}function M(e={}){let{query:t,...r}=e,i=D(r),a=_({...t,signal:i.disposalSignal}),c=a,u=j(i),d=new Set;async function f(e,t,r,a,s,c){let u=t.signal,d;try{d=await i.dispatch({headers:e,init:t,url:r})}catch(e){throw l(e,a,r,u)}if(!d.ok){let e=d.headers.get(`content-type`)?.includes(`json`)??!1,t=await d.text().catch(()=>``),i=t;if(t&&e)try{i=JSON.parse(t)}catch{}throw n.fromResponse(d,i,a,r)}let f;try{f=await y(d,s??`auto`)}catch(e){throw l(e,a,r,u)}if(c)try{return c.parse(f)}catch(e){throw new o(e,f)}return f}async function p(e,t,n={}){if(i.disposed)throw new s(`Courier`);let r=e.toUpperCase(),a;try{a=O(i.baseUrl,t,n.params,n.query)}catch(e){throw l(e,r,t)}let{body:o,fetchInit:c,headers:u,responseType:d,schema:p,signal:m,timeout:h}=n;h!==void 0&&T(h);let g=new AbortController,_=i.track(g),v=E(h??i.getTimeout(),C(m,g.signal)),{headers:y,...x}=b(r,i.mergeHeaders(u),o,v,c??{});try{return await f(y,x,a,r,d,p)}finally{_()}}return{cancelAll(){i.cancelAll(),a.cancelAll();for(let e of d)e.abort()},delete:(e,t)=>p(`DELETE`,e,t),get disposalSignal(){return i.disposalSignal},dispose(){for(let e of d)e.abort();d.clear(),c.clear(),i.dispose()},get disposed(){return i.disposed},events:u.events,get:(e,t)=>p(`GET`,e,t),getHeaders:i.getHeaders,mutate:async e=>{if(i.disposed)throw new s(`Courier`);let t=new AbortController;d.add(t);let n=C(e.signal,t.signal,i.disposalSignal)??t.signal;try{let t=await e.request({signal:n});await e.onSuccess?.(t,c);for(let t of e.invalidateKeys??[])c.invalidate(t,{refetch:!0});return t}finally{d.delete(t)}},patch:(e,t)=>p(`PATCH`,e,t),post:(e,t)=>p(`POST`,e,t),put:(e,t)=>p(`PUT`,e,t),queries:c,read:u.read,setHeaders:i.setHeaders,[Symbol.dispose](){this.dispose()},use:i.use}}function N(){return crypto.randomUUID()}function P(e){return async(t,n)=>{let r=typeof e==`function`?await e():e;return n(t.withHeaders({authorization:`Bearer ${r}`}))}}function F(e){let t=e?.header??`x-request-id`,n=e?.generate??N;return(e,r)=>r(e.withHeaders({[t]:n()}))}function I(e){let t=e.logger;return async(e,n)=>{let r=performance.now(),i=(e.init.method??`GET`).toUpperCase();try{let a=await n(e),o=Math.round(performance.now()-r);return t(`${i} ${e.url} ${a.status} (${o}ms)`,{duration:o,method:i,status:a.status,url:e.url}),a}catch(n){let a=Math.round(performance.now()-r);throw t(`${i} ${e.url} ERR (${a}ms)`,{duration:a,method:i,status:0,url:e.url}),n}}}return e.CourierAbortError=a,e.CourierDisposedError=s,e.CourierError=t,e.CourierHttpError=n,e.CourierNetworkError=r,e.CourierParseError=c,e.CourierSchemaValidationError=o,e.CourierTimeoutError=i,e.createCourier=M,e.withBearerAuth=P,e.withLogging=I,e.withRequestId=F,e})({});
6
6
  //# sourceMappingURL=courier.iife.js.map