@stacksjs/http 0.75.215 → 0.75.217

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.
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
- * `fetch` wrapper that aborts after `timeoutMs` and honors `Retry-After`
3
- * on 429/503 responses with exponential backoff.
2
+ * `fetch` wrapper with one budget for requests and retry waits. Honors
3
+ * numeric and HTTP-date `Retry-After` on 429/503 responses.
4
4
  *
5
- * Platform `fetch()` has no timeout — a misbehaving upstream that accepts
5
+ * Platform `fetch()` has no timeout. A misbehaving upstream that accepts
6
6
  * the connection but never sends bytes leaves the caller hanging forever.
7
7
  * Worse, every driver (Stripe webhooks, Twilio, AI providers) shares the
8
8
  * same code path, so one slow upstream cascades into stalled queue
@@ -11,8 +11,13 @@
11
11
  *
12
12
  * @param input URL or Request, exactly like fetch
13
13
  * @param init RequestInit + { timeoutMs?: number, retry?: number }
14
- * - timeoutMs (default 30_000) — overall request budget
15
- * - retry (default 0) — retry count on 429/503
14
+ * - timeoutMs (default 30_000): overall request budget
15
+ * - retry (default 0): retry count on 429/503
16
+ *
17
+ * The budget ends when response headers arrive; the caller owns subsequent
18
+ * body consumption. Streaming request bodies are sent once, because replaying
19
+ * a consumed stream cannot reproduce the upload. Use buffered bytes for an
20
+ * idempotent upload that needs retries. A Request with a body is also one-shot.
16
21
  *
17
22
  * @example
18
23
  * ```ts
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- var L;((T)=>{T[T.HTTP_CONTINUE=100]="HTTP_CONTINUE";T[T.HTTP_SWITCHING_PROTOCOLS=101]="HTTP_SWITCHING_PROTOCOLS";T[T.HTTP_OK=200]="HTTP_OK";T[T.HTTP_CREATED=201]="HTTP_CREATED";T[T.HTTP_ACCEPTED=202]="HTTP_ACCEPTED";T[T.HTTP_NON_AUTHORITATIVE_INFORMATION=203]="HTTP_NON_AUTHORITATIVE_INFORMATION";T[T.HTTP_NO_CONTENT=204]="HTTP_NO_CONTENT";T[T.HTTP_RESET_CONTENT=205]="HTTP_RESET_CONTENT";T[T.HTTP_PARTIAL_CONTENT=206]="HTTP_PARTIAL_CONTENT";T[T.HTTP_MULTIPLE_CHOICES=300]="HTTP_MULTIPLE_CHOICES";T[T.HTTP_MOVED_PERMANENTLY=301]="HTTP_MOVED_PERMANENTLY";T[T.HTTP_FOUND=302]="HTTP_FOUND";T[T.HTTP_SEE_OTHER=303]="HTTP_SEE_OTHER";T[T.HTTP_NOT_MODIFIED=304]="HTTP_NOT_MODIFIED";T[T.HTTP_USE_PROXY=305]="HTTP_USE_PROXY";T[T.HTTP_UNUSED=306]="HTTP_UNUSED";T[T.HTTP_TEMPORARY_REDIRECT=307]="HTTP_TEMPORARY_REDIRECT";T[T.HTTP_PERMANENT_REDIRECT=308]="HTTP_PERMANENT_REDIRECT";T[T.HTTP_BAD_REQUEST=400]="HTTP_BAD_REQUEST";T[T.HTTP_UNAUTHORIZED=401]="HTTP_UNAUTHORIZED";T[T.HTTP_PAYMENT_REQUIRED=402]="HTTP_PAYMENT_REQUIRED";T[T.HTTP_FORBIDDEN=403]="HTTP_FORBIDDEN";T[T.HTTP_NOT_FOUND=404]="HTTP_NOT_FOUND";T[T.HTTP_METHOD_NOT_ALLOWED=405]="HTTP_METHOD_NOT_ALLOWED";T[T.HTTP_NOT_ACCEPTABLE=406]="HTTP_NOT_ACCEPTABLE";T[T.HTTP_PROXY_AUTHENTICATION_REQUIRED=407]="HTTP_PROXY_AUTHENTICATION_REQUIRED";T[T.HTTP_REQUEST_TIMEOUT=408]="HTTP_REQUEST_TIMEOUT";T[T.HTTP_CONFLICT=409]="HTTP_CONFLICT";T[T.HTTP_GONE=410]="HTTP_GONE";T[T.HTTP_LENGTH_REQUIRED=411]="HTTP_LENGTH_REQUIRED";T[T.HTTP_PRECONDITION_FAILED=412]="HTTP_PRECONDITION_FAILED";T[T.HTTP_REQUEST_ENTITY_TOO_LARGE=413]="HTTP_REQUEST_ENTITY_TOO_LARGE";T[T.HTTP_REQUEST_URI_TOO_LONG=414]="HTTP_REQUEST_URI_TOO_LONG";T[T.HTTP_UNSUPPORTED_MEDIA_TYPE=415]="HTTP_UNSUPPORTED_MEDIA_TYPE";T[T.HTTP_REQUESTED_RANGE_NOT_SATISFIABLE=416]="HTTP_REQUESTED_RANGE_NOT_SATISFIABLE";T[T.HTTP_EXPECTATION_FAILED=417]="HTTP_EXPECTATION_FAILED";T[T.HTTP_I_AM_A_TEAPOT=418]="HTTP_I_AM_A_TEAPOT";T[T.HTTP_MISDIRECTED_REQUEST=421]="HTTP_MISDIRECTED_REQUEST";T[T.HTTP_UNPROCESSABLE_ENTITY=422]="HTTP_UNPROCESSABLE_ENTITY";T[T.HTTP_LOCKED=423]="HTTP_LOCKED";T[T.HTTP_FAILED_DEPENDENCY=424]="HTTP_FAILED_DEPENDENCY";T[T.HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL=425]="HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL";T[T.HTTP_UPGRADE_REQUIRED=426]="HTTP_UPGRADE_REQUIRED";T[T.HTTP_PRECONDITION_REQUIRED=428]="HTTP_PRECONDITION_REQUIRED";T[T.HTTP_TOO_MANY_REQUESTS=429]="HTTP_TOO_MANY_REQUESTS";T[T.HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE=431]="HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE";T[T.HTTP_UNAVAILABLE_FOR_LEGAL_REASONS=451]="HTTP_UNAVAILABLE_FOR_LEGAL_REASONS";T[T.HTTP_INTERNAL_SERVER_ERROR=500]="HTTP_INTERNAL_SERVER_ERROR";T[T.HTTP_NOT_IMPLEMENTED=501]="HTTP_NOT_IMPLEMENTED";T[T.HTTP_BAD_GATEWAY=502]="HTTP_BAD_GATEWAY";T[T.HTTP_SERVICE_UNAVAILABLE=503]="HTTP_SERVICE_UNAVAILABLE";T[T.HTTP_GATEWAY_TIMEOUT=504]="HTTP_GATEWAY_TIMEOUT";T[T.HTTP_VERSION_NOT_SUPPORTED=505]="HTTP_VERSION_NOT_SUPPORTED";T[T.HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL=506]="HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL";T[T.HTTP_INSUFFICIENT_STORAGE=507]="HTTP_INSUFFICIENT_STORAGE";T[T.HTTP_LOOP_DETECTED=508]="HTTP_LOOP_DETECTED";T[T.HTTP_NOT_EXTENDED=510]="HTTP_NOT_EXTENDED";T[T.HTTP_NETWORK_AUTHENTICATION_REQUIRED=511]="HTTP_NETWORK_AUTHENTICATION_REQUIRED"})(L||={});async function C(H,I={}){let{timeoutMs:O=30000,retry:A=0,...t}=I,_=0;while(!0){let N=new AbortController,D=setTimeout(()=>N.abort(Error(`Request timed out after ${O}ms`)),O);try{let E=await fetch(H,{...t,signal:N.signal});if((E.status===429||E.status===503)&&_<A){let P=Number(E.headers.get("retry-after")),U=(Number.isFinite(P)&&P>0?P:2**_)*1000;await new Promise((S)=>setTimeout(S,Math.min(U,30000))),_++;continue}return E}finally{clearTimeout(D)}}}export{L as Response,C as fetchWithBudget};
2
+ var m;((T)=>{T[T.HTTP_CONTINUE=100]="HTTP_CONTINUE";T[T.HTTP_SWITCHING_PROTOCOLS=101]="HTTP_SWITCHING_PROTOCOLS";T[T.HTTP_OK=200]="HTTP_OK";T[T.HTTP_CREATED=201]="HTTP_CREATED";T[T.HTTP_ACCEPTED=202]="HTTP_ACCEPTED";T[T.HTTP_NON_AUTHORITATIVE_INFORMATION=203]="HTTP_NON_AUTHORITATIVE_INFORMATION";T[T.HTTP_NO_CONTENT=204]="HTTP_NO_CONTENT";T[T.HTTP_RESET_CONTENT=205]="HTTP_RESET_CONTENT";T[T.HTTP_PARTIAL_CONTENT=206]="HTTP_PARTIAL_CONTENT";T[T.HTTP_MULTIPLE_CHOICES=300]="HTTP_MULTIPLE_CHOICES";T[T.HTTP_MOVED_PERMANENTLY=301]="HTTP_MOVED_PERMANENTLY";T[T.HTTP_FOUND=302]="HTTP_FOUND";T[T.HTTP_SEE_OTHER=303]="HTTP_SEE_OTHER";T[T.HTTP_NOT_MODIFIED=304]="HTTP_NOT_MODIFIED";T[T.HTTP_USE_PROXY=305]="HTTP_USE_PROXY";T[T.HTTP_UNUSED=306]="HTTP_UNUSED";T[T.HTTP_TEMPORARY_REDIRECT=307]="HTTP_TEMPORARY_REDIRECT";T[T.HTTP_PERMANENT_REDIRECT=308]="HTTP_PERMANENT_REDIRECT";T[T.HTTP_BAD_REQUEST=400]="HTTP_BAD_REQUEST";T[T.HTTP_UNAUTHORIZED=401]="HTTP_UNAUTHORIZED";T[T.HTTP_PAYMENT_REQUIRED=402]="HTTP_PAYMENT_REQUIRED";T[T.HTTP_FORBIDDEN=403]="HTTP_FORBIDDEN";T[T.HTTP_NOT_FOUND=404]="HTTP_NOT_FOUND";T[T.HTTP_METHOD_NOT_ALLOWED=405]="HTTP_METHOD_NOT_ALLOWED";T[T.HTTP_NOT_ACCEPTABLE=406]="HTTP_NOT_ACCEPTABLE";T[T.HTTP_PROXY_AUTHENTICATION_REQUIRED=407]="HTTP_PROXY_AUTHENTICATION_REQUIRED";T[T.HTTP_REQUEST_TIMEOUT=408]="HTTP_REQUEST_TIMEOUT";T[T.HTTP_CONFLICT=409]="HTTP_CONFLICT";T[T.HTTP_GONE=410]="HTTP_GONE";T[T.HTTP_LENGTH_REQUIRED=411]="HTTP_LENGTH_REQUIRED";T[T.HTTP_PRECONDITION_FAILED=412]="HTTP_PRECONDITION_FAILED";T[T.HTTP_REQUEST_ENTITY_TOO_LARGE=413]="HTTP_REQUEST_ENTITY_TOO_LARGE";T[T.HTTP_REQUEST_URI_TOO_LONG=414]="HTTP_REQUEST_URI_TOO_LONG";T[T.HTTP_UNSUPPORTED_MEDIA_TYPE=415]="HTTP_UNSUPPORTED_MEDIA_TYPE";T[T.HTTP_REQUESTED_RANGE_NOT_SATISFIABLE=416]="HTTP_REQUESTED_RANGE_NOT_SATISFIABLE";T[T.HTTP_EXPECTATION_FAILED=417]="HTTP_EXPECTATION_FAILED";T[T.HTTP_I_AM_A_TEAPOT=418]="HTTP_I_AM_A_TEAPOT";T[T.HTTP_MISDIRECTED_REQUEST=421]="HTTP_MISDIRECTED_REQUEST";T[T.HTTP_UNPROCESSABLE_ENTITY=422]="HTTP_UNPROCESSABLE_ENTITY";T[T.HTTP_LOCKED=423]="HTTP_LOCKED";T[T.HTTP_FAILED_DEPENDENCY=424]="HTTP_FAILED_DEPENDENCY";T[T.HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL=425]="HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL";T[T.HTTP_UPGRADE_REQUIRED=426]="HTTP_UPGRADE_REQUIRED";T[T.HTTP_PRECONDITION_REQUIRED=428]="HTTP_PRECONDITION_REQUIRED";T[T.HTTP_TOO_MANY_REQUESTS=429]="HTTP_TOO_MANY_REQUESTS";T[T.HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE=431]="HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE";T[T.HTTP_UNAVAILABLE_FOR_LEGAL_REASONS=451]="HTTP_UNAVAILABLE_FOR_LEGAL_REASONS";T[T.HTTP_INTERNAL_SERVER_ERROR=500]="HTTP_INTERNAL_SERVER_ERROR";T[T.HTTP_NOT_IMPLEMENTED=501]="HTTP_NOT_IMPLEMENTED";T[T.HTTP_BAD_GATEWAY=502]="HTTP_BAD_GATEWAY";T[T.HTTP_SERVICE_UNAVAILABLE=503]="HTTP_SERVICE_UNAVAILABLE";T[T.HTTP_GATEWAY_TIMEOUT=504]="HTTP_GATEWAY_TIMEOUT";T[T.HTTP_VERSION_NOT_SUPPORTED=505]="HTTP_VERSION_NOT_SUPPORTED";T[T.HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL=506]="HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL";T[T.HTTP_INSUFFICIENT_STORAGE=507]="HTTP_INSUFFICIENT_STORAGE";T[T.HTTP_LOOP_DETECTED=508]="HTTP_LOOP_DETECTED";T[T.HTTP_NOT_EXTENDED=510]="HTTP_NOT_EXTENDED";T[T.HTTP_NETWORK_AUTHENTICATION_REQUIRED=511]="HTTP_NETWORK_AUTHENTICATION_REQUIRED"})(m||={});async function c(E,_={}){let{timeoutMs:t=30000,retry:O=0,...r}=_;if(!Number.isFinite(t)||t<=0||t>2147483647)throw RangeError("timeoutMs must be positive and within the platform timer range");if(!Number.isSafeInteger(O)||O<0)throw RangeError("retry must be a non-negative safe integer");let P=new AbortController,H=r.signal??(E instanceof Request?E.signal:void 0),I=H?AbortSignal.any([H,P.signal]):P.signal,S=!(r.body instanceof ReadableStream)&&!(E instanceof Request&&E.body!==null),U=setTimeout(()=>P.abort(Error(`Request timed out after ${t}ms`)),t);try{for(let a=0;;a++){I.throwIfAborted();let A=await fetch(E,{...r,signal:I});if(!S||![429,503].includes(A.status)||a>=O)return A;let N=A.headers.get("retry-after")?.trim(),i=N&&/^\d+(?:\.\d+)?$/.test(N)?Number(N):NaN,D=N&&/^[a-z]{3}(?:[a-z]*,| )/i.test(N)?Date.parse(N):NaN,L=Number.isFinite(i)?i*1000:Number.isFinite(D)?Math.max(0,D-Date.now()):Math.min(2**a*1000,30000);await A.body?.cancel(),await C(L,I)}}finally{clearTimeout(U)}}function C(E,_){return _.throwIfAborted(),new Promise((t,O)=>{let r=()=>{clearTimeout(H),_.removeEventListener("abort",P)},P=()=>{r(),O(_.reason)},H=setTimeout(()=>{r(),t()},Math.min(E,2147483647));if(_.addEventListener("abort",P,{once:!0}),_.aborted)P()})}export{m as Response,c as fetchWithBudget};
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/http",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.215",
5
+ "version": "0.75.217",
6
6
  "description": "Stacks HTTP methods.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [