@fetchkit/ffetch 5.1.1 → 5.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.
package/README.md CHANGED
@@ -67,6 +67,7 @@ ffetch uses a plugin architecture for optional features, so you only include wha
67
67
  - **Deduplication plugin (optional, prebuilt)** – automatic deduping of in-flight identical requests
68
68
  - **Request shortcuts plugin (optional, prebuilt)** – call `client.get(url)` / `.post()` / `.put()` / `.patch()` / `.delete()` directly on the client
69
69
  - **Response shortcuts plugin (optional, prebuilt)** – call `client(url).json()` / `.text()` / `.blob()` directly on the request promise
70
+ - **Download progress plugin (optional, prebuilt)** – stream download progress callbacks with bytes transferred and percentage
70
71
 
71
72
  **Built-in error classes:** `TimeoutError`, `RetryLimitError`, `CircuitOpenError`, `HttpError`, `NetworkError`, `AbortError`
72
73
 
@@ -78,6 +79,7 @@ All plugins are tree-shakeable — import only what you use.
78
79
  - **circuitPlugin (optional)**: fail fast after repeated failures.
79
80
  - **requestShortcutsPlugin (optional)**: HTTP method shortcuts on the client (`.get()` / `.post()` / `.put()` / `.patch()` / `.delete()` / `.head()` / `.options()`).
80
81
  - **responseShortcutsPlugin (optional)**: use `client(url).json()` / `.text()` / `.blob()` style parsing.
82
+ - **downloadProgressPlugin (optional)**: stream download progress via `onProgress(progress, chunk)` callback.
81
83
 
82
84
  ## What Problems Does ffetch Solve?
83
85
 
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/plugins/download-progress.ts
21
+ var download_progress_exports = {};
22
+ __export(download_progress_exports, {
23
+ downloadProgressPlugin: () => downloadProgressPlugin
24
+ });
25
+ module.exports = __toCommonJS(download_progress_exports);
26
+ function downloadProgressPlugin(onProgress) {
27
+ return {
28
+ name: "downloadProgress",
29
+ wrapDispatch: (next) => async (ctx) => {
30
+ const response = await next(ctx);
31
+ if (!response.body) {
32
+ return response;
33
+ }
34
+ const contentLength = response.headers.get("content-length");
35
+ const totalBytes = contentLength ? parseInt(contentLength, 10) : 0;
36
+ let transferredBytes = 0;
37
+ const stream = response.body.pipeThrough(
38
+ new TransformStream({
39
+ transform(chunk, controller) {
40
+ transferredBytes += chunk.byteLength;
41
+ const percent = totalBytes > 0 ? transferredBytes / totalBytes : 0;
42
+ onProgress({ percent, transferredBytes, totalBytes }, chunk);
43
+ controller.enqueue(chunk);
44
+ }
45
+ })
46
+ );
47
+ return new Response(stream, {
48
+ status: response.status,
49
+ statusText: response.statusText,
50
+ headers: response.headers
51
+ });
52
+ }
53
+ };
54
+ }
55
+ // Annotate the CommonJS export names for ESM import in node:
56
+ 0 && (module.exports = {
57
+ downloadProgressPlugin
58
+ });
59
+ //# sourceMappingURL=download-progress.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plugins/download-progress.ts"],"sourcesContent":["import type { ClientPlugin } from '../plugins.js'\n\nexport type DownloadProgressEvent = {\n percent: number\n transferredBytes: number\n totalBytes: number\n}\n\nexport type DownloadProgressCallback = (\n progress: DownloadProgressEvent,\n chunk: Uint8Array\n) => void\n\nexport function downloadProgressPlugin(\n onProgress: DownloadProgressCallback\n): ClientPlugin {\n return {\n name: 'downloadProgress',\n wrapDispatch: (next) => async (ctx) => {\n const response = await next(ctx)\n\n if (!response.body) {\n return response\n }\n\n const contentLength = response.headers.get('content-length')\n const totalBytes = contentLength ? parseInt(contentLength, 10) : 0\n let transferredBytes = 0\n\n const stream = response.body.pipeThrough(\n new TransformStream<Uint8Array, Uint8Array>({\n transform(chunk, controller) {\n transferredBytes += chunk.byteLength\n const percent = totalBytes > 0 ? transferredBytes / totalBytes : 0\n onProgress({ percent, transferredBytes, totalBytes }, chunk)\n controller.enqueue(chunk)\n },\n })\n )\n\n return new Response(stream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n })\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAaO,SAAS,uBACd,YACc;AACd,SAAO;AAAA,IACL,MAAM;AAAA,IACN,cAAc,CAAC,SAAS,OAAO,QAAQ;AACrC,YAAM,WAAW,MAAM,KAAK,GAAG;AAE/B,UAAI,CAAC,SAAS,MAAM;AAClB,eAAO;AAAA,MACT;AAEA,YAAM,gBAAgB,SAAS,QAAQ,IAAI,gBAAgB;AAC3D,YAAM,aAAa,gBAAgB,SAAS,eAAe,EAAE,IAAI;AACjE,UAAI,mBAAmB;AAEvB,YAAM,SAAS,SAAS,KAAK;AAAA,QAC3B,IAAI,gBAAwC;AAAA,UAC1C,UAAU,OAAO,YAAY;AAC3B,gCAAoB,MAAM;AAC1B,kBAAM,UAAU,aAAa,IAAI,mBAAmB,aAAa;AACjE,uBAAW,EAAE,SAAS,kBAAkB,WAAW,GAAG,KAAK;AAC3D,uBAAW,QAAQ,KAAK;AAAA,UAC1B;AAAA,QACF,CAAC;AAAA,MACH;AAEA,aAAO,IAAI,SAAS,QAAQ;AAAA,QAC1B,QAAQ,SAAS;AAAA,QACjB,YAAY,SAAS;AAAA,QACrB,SAAS,SAAS;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,11 @@
1
+ import { C as ClientPlugin } from '../plugins-DqBQVM4I.cjs';
2
+
3
+ type DownloadProgressEvent = {
4
+ percent: number;
5
+ transferredBytes: number;
6
+ totalBytes: number;
7
+ };
8
+ type DownloadProgressCallback = (progress: DownloadProgressEvent, chunk: Uint8Array) => void;
9
+ declare function downloadProgressPlugin(onProgress: DownloadProgressCallback): ClientPlugin;
10
+
11
+ export { type DownloadProgressCallback, type DownloadProgressEvent, downloadProgressPlugin };
@@ -0,0 +1,11 @@
1
+ import { C as ClientPlugin } from '../plugins-DqBQVM4I.js';
2
+
3
+ type DownloadProgressEvent = {
4
+ percent: number;
5
+ transferredBytes: number;
6
+ totalBytes: number;
7
+ };
8
+ type DownloadProgressCallback = (progress: DownloadProgressEvent, chunk: Uint8Array) => void;
9
+ declare function downloadProgressPlugin(onProgress: DownloadProgressCallback): ClientPlugin;
10
+
11
+ export { type DownloadProgressCallback, type DownloadProgressEvent, downloadProgressPlugin };
@@ -0,0 +1,34 @@
1
+ // src/plugins/download-progress.ts
2
+ function downloadProgressPlugin(onProgress) {
3
+ return {
4
+ name: "downloadProgress",
5
+ wrapDispatch: (next) => async (ctx) => {
6
+ const response = await next(ctx);
7
+ if (!response.body) {
8
+ return response;
9
+ }
10
+ const contentLength = response.headers.get("content-length");
11
+ const totalBytes = contentLength ? parseInt(contentLength, 10) : 0;
12
+ let transferredBytes = 0;
13
+ const stream = response.body.pipeThrough(
14
+ new TransformStream({
15
+ transform(chunk, controller) {
16
+ transferredBytes += chunk.byteLength;
17
+ const percent = totalBytes > 0 ? transferredBytes / totalBytes : 0;
18
+ onProgress({ percent, transferredBytes, totalBytes }, chunk);
19
+ controller.enqueue(chunk);
20
+ }
21
+ })
22
+ );
23
+ return new Response(stream, {
24
+ status: response.status,
25
+ statusText: response.statusText,
26
+ headers: response.headers
27
+ });
28
+ }
29
+ };
30
+ }
31
+ export {
32
+ downloadProgressPlugin
33
+ };
34
+ //# sourceMappingURL=download-progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plugins/download-progress.ts"],"sourcesContent":["import type { ClientPlugin } from '../plugins.js'\n\nexport type DownloadProgressEvent = {\n percent: number\n transferredBytes: number\n totalBytes: number\n}\n\nexport type DownloadProgressCallback = (\n progress: DownloadProgressEvent,\n chunk: Uint8Array\n) => void\n\nexport function downloadProgressPlugin(\n onProgress: DownloadProgressCallback\n): ClientPlugin {\n return {\n name: 'downloadProgress',\n wrapDispatch: (next) => async (ctx) => {\n const response = await next(ctx)\n\n if (!response.body) {\n return response\n }\n\n const contentLength = response.headers.get('content-length')\n const totalBytes = contentLength ? parseInt(contentLength, 10) : 0\n let transferredBytes = 0\n\n const stream = response.body.pipeThrough(\n new TransformStream<Uint8Array, Uint8Array>({\n transform(chunk, controller) {\n transferredBytes += chunk.byteLength\n const percent = totalBytes > 0 ? transferredBytes / totalBytes : 0\n onProgress({ percent, transferredBytes, totalBytes }, chunk)\n controller.enqueue(chunk)\n },\n })\n )\n\n return new Response(stream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n })\n },\n }\n}\n"],"mappings":";AAaO,SAAS,uBACd,YACc;AACd,SAAO;AAAA,IACL,MAAM;AAAA,IACN,cAAc,CAAC,SAAS,OAAO,QAAQ;AACrC,YAAM,WAAW,MAAM,KAAK,GAAG;AAE/B,UAAI,CAAC,SAAS,MAAM;AAClB,eAAO;AAAA,MACT;AAEA,YAAM,gBAAgB,SAAS,QAAQ,IAAI,gBAAgB;AAC3D,YAAM,aAAa,gBAAgB,SAAS,eAAe,EAAE,IAAI;AACjE,UAAI,mBAAmB;AAEvB,YAAM,SAAS,SAAS,KAAK;AAAA,QAC3B,IAAI,gBAAwC;AAAA,UAC1C,UAAU,OAAO,YAAY;AAC3B,gCAAoB,MAAM;AAC1B,kBAAM,UAAU,aAAa,IAAI,mBAAmB,aAAa;AACjE,uBAAW,EAAE,SAAS,kBAAkB,WAAW,GAAG,KAAK;AAC3D,uBAAW,QAAQ,KAAK;AAAA,UAC1B;AAAA,QACF,CAAC;AAAA,MACH;AAEA,aAAO,IAAI,SAAS,QAAQ;AAAA,QAC1B,QAAQ,SAAS;AAAA,QACjB,YAAY,SAAS;AAAA,QACrB,SAAS,SAAS;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fetchkit/ffetch",
3
- "version": "5.1.1",
3
+ "version": "5.2.0",
4
4
  "description": "Fetch wrapper with configurable timeouts, retries, and TypeScript-first DX",
5
5
  "keywords": [
6
6
  "fetch",
@@ -46,6 +46,11 @@
46
46
  "types": "./dist/plugins/request-shortcuts.d.ts",
47
47
  "import": "./dist/plugins/request-shortcuts.js",
48
48
  "require": "./dist/plugins/request-shortcuts.cjs"
49
+ },
50
+ "./plugins/download-progress": {
51
+ "types": "./dist/plugins/download-progress.d.ts",
52
+ "import": "./dist/plugins/download-progress.js",
53
+ "require": "./dist/plugins/download-progress.cjs"
49
54
  }
50
55
  },
51
56
  "files": [