@fetchkit/ffetch 5.1.0 → 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":[]}
@@ -23,9 +23,10 @@ __export(response_shortcuts_exports, {
23
23
  responseShortcutsPlugin: () => responseShortcutsPlugin
24
24
  });
25
25
  module.exports = __toCommonJS(response_shortcuts_exports);
26
+ var DECORATED = Symbol("ffetch.responseShortcutsDecorated");
26
27
  function attachResponseShortcuts(promise) {
27
28
  const decorated = promise;
28
- if (decorated.__ffetchResponseShortcutsDecorated__) {
29
+ if (decorated[DECORATED]) {
29
30
  return decorated;
30
31
  }
31
32
  Object.defineProperties(decorated, {
@@ -69,7 +70,7 @@ function attachResponseShortcuts(promise) {
69
70
  enumerable: false,
70
71
  configurable: false
71
72
  },
72
- __ffetchResponseShortcutsDecorated__: {
73
+ [DECORATED]: {
73
74
  value: true,
74
75
  writable: false,
75
76
  enumerable: false,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugins/response-shortcuts.ts"],"sourcesContent":["import type { ClientPlugin } from '../plugins.js'\r\n\r\nexport type ResponseShortcuts = {\r\n json: <T = unknown>() => Promise<T>\r\n text: () => Promise<string>\r\n blob: () => Promise<Blob>\r\n arrayBuffer: () => Promise<ArrayBuffer>\r\n formData: () => Promise<FormData>\r\n}\r\n\r\ntype ResponseShortcutsPromise = Promise<Response> & ResponseShortcuts\r\n\r\ntype DecoratedPromise = ResponseShortcutsPromise & {\r\n __ffetchResponseShortcutsDecorated__?: true\r\n}\r\n\r\nfunction attachResponseShortcuts(\r\n promise: Promise<Response>\r\n): ResponseShortcutsPromise {\r\n const decorated = promise as DecoratedPromise\r\n\r\n if (decorated.__ffetchResponseShortcutsDecorated__) {\r\n return decorated\r\n }\r\n\r\n Object.defineProperties(decorated, {\r\n json: {\r\n value: function json<T = unknown>(this: Promise<Response>) {\r\n return this.then((response) => response.json() as Promise<T>)\r\n },\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n },\r\n text: {\r\n value: function text(this: Promise<Response>) {\r\n return this.then((response) => response.text())\r\n },\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n },\r\n blob: {\r\n value: function blob(this: Promise<Response>) {\r\n return this.then((response) => response.blob())\r\n },\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n },\r\n arrayBuffer: {\r\n value: function arrayBuffer(this: Promise<Response>) {\r\n return this.then((response) => response.arrayBuffer())\r\n },\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n },\r\n formData: {\r\n value: function formData(this: Promise<Response>) {\r\n return this.then((response) => response.formData())\r\n },\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n },\r\n __ffetchResponseShortcutsDecorated__: {\r\n value: true,\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n },\r\n })\r\n\r\n return decorated\r\n}\r\n\r\nexport function responseShortcutsPlugin(): ClientPlugin<\r\n Record<never, never>,\r\n ResponseShortcuts\r\n> {\r\n return {\r\n name: 'response-shortcuts',\r\n decoratePromise: (promise) => attachResponseShortcuts(promise),\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,SAAS,wBACP,SAC0B;AAC1B,QAAM,YAAY;AAElB,MAAI,UAAU,sCAAsC;AAClD,WAAO;AAAA,EACT;AAEA,SAAO,iBAAiB,WAAW;AAAA,IACjC,MAAM;AAAA,MACJ,OAAO,SAAS,OAA2C;AACzD,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,KAAK,CAAe;AAAA,MAC9D;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,SAAS,OAA8B;AAC5C,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,KAAK,CAAC;AAAA,MAChD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,SAAS,OAA8B;AAC5C,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,KAAK,CAAC;AAAA,MAChD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,aAAa;AAAA,MACX,OAAO,SAAS,cAAqC;AACnD,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,YAAY,CAAC;AAAA,MACvD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,UAAU;AAAA,MACR,OAAO,SAAS,WAAkC;AAChD,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,SAAS,CAAC;AAAA,MACpD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,sCAAsC;AAAA,MACpC,OAAO;AAAA,MACP,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEO,SAAS,0BAGd;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,iBAAiB,CAAC,YAAY,wBAAwB,OAAO;AAAA,EAC/D;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/plugins/response-shortcuts.ts"],"sourcesContent":["import type { ClientPlugin } from '../plugins.js'\n\nexport type ResponseShortcuts = {\n json: <T = unknown>() => Promise<T>\n text: () => Promise<string>\n blob: () => Promise<Blob>\n arrayBuffer: () => Promise<ArrayBuffer>\n formData: () => Promise<FormData>\n}\n\ntype ResponseShortcutsPromise = Promise<Response> & ResponseShortcuts\n\nconst DECORATED = Symbol('ffetch.responseShortcutsDecorated')\n\ntype DecoratedPromise = ResponseShortcutsPromise & {\n [DECORATED]?: true\n}\n\nfunction attachResponseShortcuts(\n promise: Promise<Response>\n): ResponseShortcutsPromise {\n const decorated = promise as DecoratedPromise\n\n if (decorated[DECORATED]) {\n return decorated\n }\n\n Object.defineProperties(decorated, {\n json: {\n value: function json<T = unknown>(this: Promise<Response>) {\n return this.then((response) => response.json() as Promise<T>)\n },\n writable: false,\n enumerable: false,\n configurable: false,\n },\n text: {\n value: function text(this: Promise<Response>) {\n return this.then((response) => response.text())\n },\n writable: false,\n enumerable: false,\n configurable: false,\n },\n blob: {\n value: function blob(this: Promise<Response>) {\n return this.then((response) => response.blob())\n },\n writable: false,\n enumerable: false,\n configurable: false,\n },\n arrayBuffer: {\n value: function arrayBuffer(this: Promise<Response>) {\n return this.then((response) => response.arrayBuffer())\n },\n writable: false,\n enumerable: false,\n configurable: false,\n },\n formData: {\n value: function formData(this: Promise<Response>) {\n return this.then((response) => response.formData())\n },\n writable: false,\n enumerable: false,\n configurable: false,\n },\n [DECORATED]: {\n value: true,\n writable: false,\n enumerable: false,\n configurable: false,\n },\n })\n\n return decorated\n}\n\nexport function responseShortcutsPlugin(): ClientPlugin<\n Record<never, never>,\n ResponseShortcuts\n> {\n return {\n name: 'response-shortcuts',\n decoratePromise: (promise) => attachResponseShortcuts(promise),\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA,IAAM,YAAY,OAAO,mCAAmC;AAM5D,SAAS,wBACP,SAC0B;AAC1B,QAAM,YAAY;AAElB,MAAI,UAAU,SAAS,GAAG;AACxB,WAAO;AAAA,EACT;AAEA,SAAO,iBAAiB,WAAW;AAAA,IACjC,MAAM;AAAA,MACJ,OAAO,SAAS,OAA2C;AACzD,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,KAAK,CAAe;AAAA,MAC9D;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,SAAS,OAA8B;AAC5C,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,KAAK,CAAC;AAAA,MAChD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,SAAS,OAA8B;AAC5C,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,KAAK,CAAC;AAAA,MAChD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,aAAa;AAAA,MACX,OAAO,SAAS,cAAqC;AACnD,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,YAAY,CAAC;AAAA,MACvD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,UAAU;AAAA,MACR,OAAO,SAAS,WAAkC;AAChD,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,SAAS,CAAC;AAAA,MACpD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,CAAC,SAAS,GAAG;AAAA,MACX,OAAO;AAAA,MACP,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEO,SAAS,0BAGd;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,iBAAiB,CAAC,YAAY,wBAAwB,OAAO;AAAA,EAC/D;AACF;","names":[]}
@@ -1,7 +1,8 @@
1
1
  // src/plugins/response-shortcuts.ts
2
+ var DECORATED = Symbol("ffetch.responseShortcutsDecorated");
2
3
  function attachResponseShortcuts(promise) {
3
4
  const decorated = promise;
4
- if (decorated.__ffetchResponseShortcutsDecorated__) {
5
+ if (decorated[DECORATED]) {
5
6
  return decorated;
6
7
  }
7
8
  Object.defineProperties(decorated, {
@@ -45,7 +46,7 @@ function attachResponseShortcuts(promise) {
45
46
  enumerable: false,
46
47
  configurable: false
47
48
  },
48
- __ffetchResponseShortcutsDecorated__: {
49
+ [DECORATED]: {
49
50
  value: true,
50
51
  writable: false,
51
52
  enumerable: false,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugins/response-shortcuts.ts"],"sourcesContent":["import type { ClientPlugin } from '../plugins.js'\r\n\r\nexport type ResponseShortcuts = {\r\n json: <T = unknown>() => Promise<T>\r\n text: () => Promise<string>\r\n blob: () => Promise<Blob>\r\n arrayBuffer: () => Promise<ArrayBuffer>\r\n formData: () => Promise<FormData>\r\n}\r\n\r\ntype ResponseShortcutsPromise = Promise<Response> & ResponseShortcuts\r\n\r\ntype DecoratedPromise = ResponseShortcutsPromise & {\r\n __ffetchResponseShortcutsDecorated__?: true\r\n}\r\n\r\nfunction attachResponseShortcuts(\r\n promise: Promise<Response>\r\n): ResponseShortcutsPromise {\r\n const decorated = promise as DecoratedPromise\r\n\r\n if (decorated.__ffetchResponseShortcutsDecorated__) {\r\n return decorated\r\n }\r\n\r\n Object.defineProperties(decorated, {\r\n json: {\r\n value: function json<T = unknown>(this: Promise<Response>) {\r\n return this.then((response) => response.json() as Promise<T>)\r\n },\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n },\r\n text: {\r\n value: function text(this: Promise<Response>) {\r\n return this.then((response) => response.text())\r\n },\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n },\r\n blob: {\r\n value: function blob(this: Promise<Response>) {\r\n return this.then((response) => response.blob())\r\n },\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n },\r\n arrayBuffer: {\r\n value: function arrayBuffer(this: Promise<Response>) {\r\n return this.then((response) => response.arrayBuffer())\r\n },\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n },\r\n formData: {\r\n value: function formData(this: Promise<Response>) {\r\n return this.then((response) => response.formData())\r\n },\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n },\r\n __ffetchResponseShortcutsDecorated__: {\r\n value: true,\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n },\r\n })\r\n\r\n return decorated\r\n}\r\n\r\nexport function responseShortcutsPlugin(): ClientPlugin<\r\n Record<never, never>,\r\n ResponseShortcuts\r\n> {\r\n return {\r\n name: 'response-shortcuts',\r\n decoratePromise: (promise) => attachResponseShortcuts(promise),\r\n }\r\n}\r\n"],"mappings":";AAgBA,SAAS,wBACP,SAC0B;AAC1B,QAAM,YAAY;AAElB,MAAI,UAAU,sCAAsC;AAClD,WAAO;AAAA,EACT;AAEA,SAAO,iBAAiB,WAAW;AAAA,IACjC,MAAM;AAAA,MACJ,OAAO,SAAS,OAA2C;AACzD,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,KAAK,CAAe;AAAA,MAC9D;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,SAAS,OAA8B;AAC5C,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,KAAK,CAAC;AAAA,MAChD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,SAAS,OAA8B;AAC5C,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,KAAK,CAAC;AAAA,MAChD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,aAAa;AAAA,MACX,OAAO,SAAS,cAAqC;AACnD,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,YAAY,CAAC;AAAA,MACvD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,UAAU;AAAA,MACR,OAAO,SAAS,WAAkC;AAChD,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,SAAS,CAAC;AAAA,MACpD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,sCAAsC;AAAA,MACpC,OAAO;AAAA,MACP,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEO,SAAS,0BAGd;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,iBAAiB,CAAC,YAAY,wBAAwB,OAAO;AAAA,EAC/D;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/plugins/response-shortcuts.ts"],"sourcesContent":["import type { ClientPlugin } from '../plugins.js'\n\nexport type ResponseShortcuts = {\n json: <T = unknown>() => Promise<T>\n text: () => Promise<string>\n blob: () => Promise<Blob>\n arrayBuffer: () => Promise<ArrayBuffer>\n formData: () => Promise<FormData>\n}\n\ntype ResponseShortcutsPromise = Promise<Response> & ResponseShortcuts\n\nconst DECORATED = Symbol('ffetch.responseShortcutsDecorated')\n\ntype DecoratedPromise = ResponseShortcutsPromise & {\n [DECORATED]?: true\n}\n\nfunction attachResponseShortcuts(\n promise: Promise<Response>\n): ResponseShortcutsPromise {\n const decorated = promise as DecoratedPromise\n\n if (decorated[DECORATED]) {\n return decorated\n }\n\n Object.defineProperties(decorated, {\n json: {\n value: function json<T = unknown>(this: Promise<Response>) {\n return this.then((response) => response.json() as Promise<T>)\n },\n writable: false,\n enumerable: false,\n configurable: false,\n },\n text: {\n value: function text(this: Promise<Response>) {\n return this.then((response) => response.text())\n },\n writable: false,\n enumerable: false,\n configurable: false,\n },\n blob: {\n value: function blob(this: Promise<Response>) {\n return this.then((response) => response.blob())\n },\n writable: false,\n enumerable: false,\n configurable: false,\n },\n arrayBuffer: {\n value: function arrayBuffer(this: Promise<Response>) {\n return this.then((response) => response.arrayBuffer())\n },\n writable: false,\n enumerable: false,\n configurable: false,\n },\n formData: {\n value: function formData(this: Promise<Response>) {\n return this.then((response) => response.formData())\n },\n writable: false,\n enumerable: false,\n configurable: false,\n },\n [DECORATED]: {\n value: true,\n writable: false,\n enumerable: false,\n configurable: false,\n },\n })\n\n return decorated\n}\n\nexport function responseShortcutsPlugin(): ClientPlugin<\n Record<never, never>,\n ResponseShortcuts\n> {\n return {\n name: 'response-shortcuts',\n decoratePromise: (promise) => attachResponseShortcuts(promise),\n }\n}\n"],"mappings":";AAYA,IAAM,YAAY,OAAO,mCAAmC;AAM5D,SAAS,wBACP,SAC0B;AAC1B,QAAM,YAAY;AAElB,MAAI,UAAU,SAAS,GAAG;AACxB,WAAO;AAAA,EACT;AAEA,SAAO,iBAAiB,WAAW;AAAA,IACjC,MAAM;AAAA,MACJ,OAAO,SAAS,OAA2C;AACzD,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,KAAK,CAAe;AAAA,MAC9D;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,SAAS,OAA8B;AAC5C,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,KAAK,CAAC;AAAA,MAChD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,SAAS,OAA8B;AAC5C,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,KAAK,CAAC;AAAA,MAChD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,aAAa;AAAA,MACX,OAAO,SAAS,cAAqC;AACnD,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,YAAY,CAAC;AAAA,MACvD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,UAAU;AAAA,MACR,OAAO,SAAS,WAAkC;AAChD,eAAO,KAAK,KAAK,CAAC,aAAa,SAAS,SAAS,CAAC;AAAA,MACpD;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,IACA,CAAC,SAAS,GAAG;AAAA,MACX,OAAO;AAAA,MACP,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEO,SAAS,0BAGd;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,iBAAiB,CAAC,YAAY,wBAAwB,OAAO;AAAA,EAC/D;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fetchkit/ffetch",
3
- "version": "5.1.0",
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": [