@stll/fetch 0.1.0 → 0.1.1

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/README.md CHANGED
@@ -22,10 +22,11 @@ const stream = await fetchWithTimeout(url, {
22
22
 
23
23
  The timeout is required by the type. `headers` bounds the wait for the
24
24
  response; `idle` also restarts on every body chunk and errors the body stream
25
- when it stalls. A timeout rejects (or errors the body) with a `TimeoutError`
26
- `DOMException`, and the caller's `signal` and a `Request`'s own signal still
27
- abort the request. `timeoutMs: number` is a total deadline over the request
28
- and its body.
25
+ when it stalls; `total` bounds the request and its body consumption through
26
+ the transport's own signal and returns the transport's response unchanged. A
27
+ timeout rejects (or errors the body) with a `TimeoutError` `DOMException`, and
28
+ the caller's `signal` and a `Request`'s own signal still abort the request.
29
+ `timeoutMs: number` remains the legacy numeric form of the total policy.
29
30
 
30
31
  `createFetchWithTimeout(fetcher)` returns the same function over another
31
32
  `fetch` implementation (a proxy-aware client, or a fake in tests).
@@ -3,6 +3,9 @@ declare const isConnectionFailure: (cause: unknown) => boolean;
3
3
  //#endregion
4
4
  //#region src/index.d.ts
5
5
  type FetchTimeout = {
6
+ type: "total";
7
+ ms: number;
8
+ } | {
6
9
  type: "headers";
7
10
  ms: number;
8
11
  } | {
@@ -18,9 +21,9 @@ type FetchWithTimeoutInit = Omit<RequestInit, "signal"> & {
18
21
  signal?: AbortSignal | undefined;
19
22
  } & ({
20
23
  timeout: FetchTimeout;
21
- timeoutMs?: never;
24
+ timeoutMs?: number;
22
25
  } | {
23
- /** Choose a headers or idle timeout for new callers. */
26
+ /** Use an explicit timeout policy for new callers. */
24
27
  timeoutMs: number;
25
28
  timeout?: never;
26
29
  });
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as createFetchWithTimeout, i as TransportRequestInit, n as FetchWithTimeoutInit, o as fetchWithTimeout, r as Fetcher, s as isConnectionFailure, t as FetchTimeout } from "./index-DNw-Gzhr.js";
1
+ import { a as createFetchWithTimeout, i as TransportRequestInit, n as FetchWithTimeoutInit, o as fetchWithTimeout, r as Fetcher, s as isConnectionFailure, t as FetchTimeout } from "./index-nwAjbSQV.js";
2
2
  export { FetchTimeout, FetchWithTimeoutInit, Fetcher, TransportRequestInit, createFetchWithTimeout, fetchWithTimeout, isConnectionFailure };
package/dist/index.js CHANGED
@@ -53,14 +53,15 @@ const isConnectionFailure = (cause) => {
53
53
  const executeFetchWithTimeout = async (fetcher, input, { timeout, timeoutMs, signal, ...init }) => {
54
54
  const callerSignals = [signal, input instanceof Request ? input.signal : void 0].filter((candidate) => candidate !== void 0);
55
55
  const activeFetcher = fetcher ?? globalThis.fetch;
56
- if (timeout === void 0) {
57
- const total = AbortSignal.timeout(timeoutMs);
58
- return await activeFetcher(input, {
59
- ...init,
60
- signal: AbortSignal.any([...callerSignals, total])
61
- });
62
- }
63
- if (!Number.isFinite(timeout.ms) || timeout.ms < 0 || timeout.ms > 2147483647) throw new DOMException("Invalid fetch timeout duration", "NotSupportedError");
56
+ const duration = timeout?.ms ?? timeoutMs;
57
+ if (typeof duration !== "number" || !Number.isFinite(duration) || duration < 0 || duration > 2147483647) throw new DOMException("Invalid fetch timeout duration", "NotSupportedError");
58
+ if (timeout === void 0 || timeout.type === "total") return await activeFetcher(input, {
59
+ ...init,
60
+ signal: AbortSignal.any([...callerSignals, AbortSignal.timeout(duration)]),
61
+ ...timeout === void 0 ? {} : { timeout },
62
+ timeoutMs: duration
63
+ });
64
+ const policy = timeout;
64
65
  const controller = new AbortController();
65
66
  const combined = AbortSignal.any([...callerSignals, controller.signal]);
66
67
  const expire = () => controller.abort(new DOMException("Fetch timed out", "TimeoutError"));
@@ -71,18 +72,20 @@ const executeFetchWithTimeout = async (fetcher, input, { timeout, timeoutMs, sig
71
72
  };
72
73
  const reset = () => {
73
74
  clear();
74
- timer = setTimeout(expire, timeout.ms);
75
+ timer = setTimeout(expire, duration);
75
76
  };
76
77
  reset();
77
78
  const response = await Promise.resolve().then(async () => await activeFetcher(input, {
78
79
  ...init,
79
- signal: combined
80
+ signal: combined,
81
+ timeout: policy,
82
+ timeoutMs: duration
80
83
  })).finally(clear);
81
84
  if (combined.aborted) {
82
85
  await Promise.allSettled([response.body?.cancel(combined.reason)]);
83
86
  throw combined.reason;
84
87
  }
85
- if (timeout.type === "headers" || response.body === null) return response;
88
+ if (policy.type === "headers" || response.body === null) return response;
86
89
  const reader = response.body.getReader();
87
90
  let stopped = false;
88
91
  let cancellation;
@@ -1,5 +1,5 @@
1
- import { i as TransportRequestInit } from "./index-DNw-Gzhr.js";
2
1
  import { Result } from "better-result";
2
+ import { i as TransportRequestInit } from "./index-nwAjbSQV.js";
3
3
  //#region src/publisher.d.ts
4
4
  export type PublisherPolicy = {
5
5
  type: "obey";
@@ -121,4 +121,5 @@ type ReadBoundedBodyOptions = {
121
121
  };
122
122
  export declare const readBoundedBody: (response: Response, { maxBytes, signal }: ReadBoundedBodyOptions) => Promise<Result<Uint8Array, PublisherBodyLimitError>>;
123
123
  export declare const createPolitePublisherFetch: <Target extends PublisherTarget>({ validateTarget, fetcher, clock, robotsTtlMs, robotsRetryMs, robotsLoadTimeoutMs, defaultMinimumIntervalMs, onTelemetry }: PublisherFetcherOptions<Target>) => (input: string | URL, options?: PublisherFetchOptions) => Promise<Result<PublisherFetchResult, PublisherPolicyError>>;
124
- //#endregion
124
+ //#endregion
125
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/fetch",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Fetch with a mandatory timeout (headers or idle body window), connection-failure classification, and a robots-aware polite publisher fetch",
5
5
  "keywords": [
6
6
  "abort",
@@ -57,7 +57,7 @@
57
57
  "@stll/typescript-config": "0.0.0",
58
58
  "bun-types": "1.4.4",
59
59
  "fast-check": "^4.10.2",
60
- "tsdown": "0.23.0"
60
+ "tsdown": "0.23.1"
61
61
  },
62
62
  "main": "./dist/index.js",
63
63
  "types": "./dist/index.d.ts"