generic-filehandle2 2.1.10 → 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.
@@ -1,3 +1,4 @@
1
+ import type { ProgressCallback } from './util.ts';
1
2
  export type BufferEncoding = 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'utf-16le' | 'ucs2' | 'ucs-2' | 'base64' | 'base64url' | 'latin1' | 'binary' | 'hex';
2
3
  export type Fetcher = (input: RequestInfo, init?: RequestInit) => Promise<Response>;
3
4
  export interface FilehandleOptions {
@@ -6,6 +7,13 @@ export interface FilehandleOptions {
6
7
  overrides?: Omit<RequestInit, 'headers'>;
7
8
  encoding?: BufferEncoding;
8
9
  fetch?: Fetcher;
10
+ /**
11
+ * Opt-in download-progress reporting. When set, the response body is streamed
12
+ * and this is called with the running byte count (and Content-Length total
13
+ * when available) as chunks arrive. Omitting it keeps the faster
14
+ * non-streaming read.
15
+ */
16
+ onProgress?: ProgressCallback;
9
17
  }
10
18
  export interface Stats {
11
19
  size: number;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './filehandle.ts';
2
+ export type { ProgressCallback } from './util.ts';
2
3
  export { default as BlobFile } from './blobFile.ts';
3
4
  export { default as RemoteFile } from './remoteFile.ts';
4
5
  export { default as LocalFile } from './localFile.ts';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,kDAA+B;AAE/B,6CAAmD;AAA1C,wHAAA,OAAO,OAAY;AAC5B,iDAAuD;AAA9C,4HAAA,OAAO,OAAc;AAC9B,+CAAqD;AAA5C,0HAAA,OAAO,OAAa"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,kDAA+B;AAG/B,6CAAmD;AAA1C,wHAAA,OAAO,OAAY;AAC5B,iDAAuD;AAA9C,4HAAA,OAAO,OAAc;AAC9B,+CAAqD;AAA5C,0HAAA,OAAO,OAAa"}
@@ -92,7 +92,9 @@ class RemoteFile {
92
92
  size: parseInt(sizeMatch[1], 10),
93
93
  };
94
94
  }
95
- const resData = await (0, util_ts_1.toBytes)(res);
95
+ const resData = opts.onProgress
96
+ ? await (0, util_ts_1.toBytesWithProgress)(res, opts.onProgress)
97
+ : await (0, util_ts_1.toBytes)(res);
96
98
  // server didn't honor the range request and returned the full file —
97
99
  // the body length is the actual file size
98
100
  if (!this._stat && res.status === 200) {
@@ -119,6 +121,9 @@ class RemoteFile {
119
121
  else if (encoding) {
120
122
  throw new Error(`unsupported encoding: ${encoding}`);
121
123
  }
124
+ else if (opts.onProgress) {
125
+ return (0, util_ts_1.toBytesWithProgress)(res, opts.onProgress);
126
+ }
122
127
  else {
123
128
  return (0, util_ts_1.toBytes)(res);
124
129
  }
@@ -1 +1 @@
1
- {"version":3,"file":"remoteFile.js","sourceRoot":"","sources":["../src/remoteFile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remoteFile.js","sourceRoot":"","sources":["../src/remoteFile.ts"],"names":[],"mappings":";;AAAA,uCAAwD;AAUxD,SAAS,UAAU,CAAC,CAAU;IAC5B,MAAM,CAAC,GACL,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,KAAK,IAAI;QACV,SAAS,IAAI,CAAC;QACd,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;QAC3B,CAAC,CAAC,CAAC,CAAC,OAAO;QACX,CAAC,CAAC,GAAG,CAAC,EAAE,CAAA;IACZ,mFAAmF;IACnF,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;AAC7B,CAAC;AAED,MAAqB,UAAU;IACnB,GAAG,CAAQ;IACb,KAAK,CAAQ;IACb,mBAAmB,CAAS;IAC5B,WAAW,CAAwB;IACnC,aAAa,CAA8B;IAEnD,YAAmB,MAAc,EAAE,OAA0B,EAAE;QAC7D,IAAI,CAAC,GAAG,GAAG,MAAM,CAAA;QACjB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAA;QACrC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAA;QACzC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC5E,CAAC;IAEO,YAAY,CAClB,IAAuB,EACvB,YAAqC;QAErC,OAAO;YACL,GAAG,IAAI,CAAC,aAAa;YACrB,GAAG,IAAI,CAAC,SAAS;YACjB,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,YAAY,EAAE;YAClE,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,QAAQ;YAClB,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAA;IACH,CAAC;IAEM,KAAK,CAAC,KAAK,CAChB,KAAkB,EAClB,IAA6B;QAE7B,MAAM,SAAS,GAAG,CAAC,CAAU,EAAE,EAAE,CAC/B,IAAI,KAAK,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,aAAa,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;QAE/D,IAAI,QAAkB,CAAA;QACtB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QACxD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACvC,yDAAyD;gBACzD,oEAAoE;gBACpE,iDAAiD;gBACjD,uDAAuD;gBACvD,OAAO,CAAC,IAAI,CACV,kCAAkC,KAAK,2DAA2D,CACnG,CAAA;gBACD,IAAI,CAAC;oBACH,QAAQ,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE;wBAC/C,GAAG,IAAI;wBACP,KAAK,EAAE,QAAQ;qBAChB,CAAC,CAAA;gBACJ,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,SAAS,CAAC,CAAC,CAAC,CAAA;gBACpB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,SAAS,CAAC,CAAC,CAAC,CAAA;YACpB,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAEM,KAAK,CAAC,IAAI,CACf,MAAc,EACd,QAAgB,EAChB,OAA0B,EAAE;QAE5B,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;YACjB,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;QAC1B,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,SAAS,CACjB,qDAAqD,MAAM,cAAc,QAAQ,mCAAmC,CACrH,CAAA;QACH,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAC1B,IAAI,CAAC,GAAG,EACR,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;YACtB,KAAK,EAAE,SAAS,QAAQ,IAAI,QAAQ,GAAG,MAAM,GAAG,CAAC,EAAE;SACpD,CAAC,CACH,CAAA;QAED,uEAAuE;QACvE,uEAAuE;QACvE,4EAA4E;QAC5E,uBAAuB;QACvB,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;QAC1B,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,MAAM,aAAa,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAC5D,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACjE,+CAA+C;YAC/C,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;YACrD,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAA;YACrD,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnB,IAAI,CAAC,KAAK,GAAG;oBACX,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;iBACjC,CAAA;YACH,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU;gBAC7B,CAAC,CAAC,MAAM,IAAA,6BAAmB,EAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC;gBACjD,CAAC,CAAC,MAAM,IAAA,iBAAO,EAAC,GAAG,CAAC,CAAA;YACtB,qEAAqE;YACrE,0CAA0C;YAC1C,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACtC,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;YAC3C,CAAC;YACD,OAAO,OAAO,CAAC,UAAU,IAAI,MAAM;gBACjC,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;QACjC,CAAC;QAED,MAAM,IAAI,KAAK,CACb,GAAG,CAAC,MAAM,KAAK,GAAG;YAChB,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,0CAA0C;YACvD,CAAC,CAAC,QAAQ,GAAG,CAAC,MAAM,aAAa,IAAI,CAAC,GAAG,EAAE,CAC9C,CAAA;IACH,CAAC;IAUM,KAAK,CAAC,QAAQ,CACnB,UAA8C,EAAE;QAEhD,MAAM,QAAQ,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAA;QACzE,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;QACvD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAA;QAC/D,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,MAAM,aAAa,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAC5D,CAAC;QACD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC,IAAI,EAAE,CAAA;QACnB,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAA;QACtD,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3B,OAAO,IAAA,6BAAmB,EAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;QAClD,CAAC;aAAM,CAAC;YACN,OAAO,IAAA,iBAAO,EAAC,GAAG,CAAC,CAAA;QACrB,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;QACxB,CAAC;QACD,sEAAsE;QACtE,mDAAmD;QACnD,OAAO,IAAI,CAAC,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAA;IAClC,CAAC;IAEM,KAAK;QACV,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IAC1B,CAAC;CACF;AArKD,6BAqKC"}
package/dist/util.d.ts CHANGED
@@ -1 +1,14 @@
1
1
  export declare function toBytes(src: Response | Blob): Promise<Uint8Array<ArrayBuffer>>;
2
+ /** Reports bytes downloaded for a single fetch; `total` from Content-Length. */
3
+ export type ProgressCallback = (bytesReceived: number, total?: number) => void;
4
+ /**
5
+ * Read a Response body to bytes while reporting download progress.
6
+ *
7
+ * When Content-Length is known the body is streamed directly into one pre-sized
8
+ * buffer (no per-chunk array, no second copy), ticking `onProgress` as chunks
9
+ * arrive. Without a known length there is no fraction to show, so it falls back
10
+ * to a single one-shot read and one completion tick rather than buffering
11
+ * chunks. Only used when a caller opts in via `onProgress`; the plain {@link
12
+ * toBytes} fast path is unaffected.
13
+ */
14
+ export declare function toBytesWithProgress(res: Response, onProgress: ProgressCallback): Promise<Uint8Array<ArrayBuffer>>;
package/dist/util.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toBytes = toBytes;
4
+ exports.toBytesWithProgress = toBytesWithProgress;
4
5
  // Response.bytes() / Blob.bytes() is widely available but not yet in all
5
6
  // lib.dom.d.ts versions, so the optional-chain check is load-bearing for older
6
7
  // runtimes despite TS thinking it's always defined.
@@ -8,4 +9,50 @@ async function toBytes(src) {
8
9
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
9
10
  return src.bytes ? src.bytes() : new Uint8Array(await src.arrayBuffer());
10
11
  }
12
+ // throttle intermediate progress ticks; a large body can yield thousands of
13
+ // chunks and the final exact count is always emitted regardless
14
+ const PROGRESS_THROTTLE_MS = 50;
15
+ /**
16
+ * Read a Response body to bytes while reporting download progress.
17
+ *
18
+ * When Content-Length is known the body is streamed directly into one pre-sized
19
+ * buffer (no per-chunk array, no second copy), ticking `onProgress` as chunks
20
+ * arrive. Without a known length there is no fraction to show, so it falls back
21
+ * to a single one-shot read and one completion tick rather than buffering
22
+ * chunks. Only used when a caller opts in via `onProgress`; the plain {@link
23
+ * toBytes} fast path is unaffected.
24
+ */
25
+ async function toBytesWithProgress(res, onProgress) {
26
+ const lengthHeader = res.headers.get('content-length');
27
+ const total = lengthHeader ? parseInt(lengthHeader, 10) : undefined;
28
+ const body = res.body;
29
+ if (!body || total === undefined) {
30
+ const bytes = await toBytes(res);
31
+ onProgress(bytes.byteLength, total ?? bytes.byteLength);
32
+ return bytes;
33
+ }
34
+ const reader = body.getReader();
35
+ let out = new Uint8Array(total);
36
+ let received = 0;
37
+ let lastTick = 0;
38
+ onProgress(0, total);
39
+ for (let chunk = await reader.read(); !chunk.done; chunk = await reader.read()) {
40
+ // a decoded body can exceed Content-Length (e.g. gzip transfer-encoding);
41
+ // grow the buffer rather than throwing on out.set() overflow
42
+ if (received + chunk.value.byteLength > out.length) {
43
+ const grown = new Uint8Array(Math.max(received + chunk.value.byteLength, out.length * 2));
44
+ grown.set(out.subarray(0, received));
45
+ out = grown;
46
+ }
47
+ out.set(chunk.value, received);
48
+ received += chunk.value.byteLength;
49
+ const now = Date.now();
50
+ if (now - lastTick >= PROGRESS_THROTTLE_MS) {
51
+ lastTick = now;
52
+ onProgress(received, total);
53
+ }
54
+ }
55
+ onProgress(received, total);
56
+ return received === out.length ? out : out.subarray(0, received);
57
+ }
11
58
  //# sourceMappingURL=util.js.map
package/dist/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;AAGA,0BAKC;AARD,yEAAyE;AACzE,+EAA+E;AAC/E,oDAAoD;AAC7C,KAAK,UAAU,OAAO,CAC3B,GAAoB;IAEpB,uEAAuE;IACvE,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAA;AAC1E,CAAC"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;AAGA,0BAKC;AAmBD,kDAuCC;AAlED,yEAAyE;AACzE,+EAA+E;AAC/E,oDAAoD;AAC7C,KAAK,UAAU,OAAO,CAC3B,GAAoB;IAEpB,uEAAuE;IACvE,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAA;AAC1E,CAAC;AAKD,4EAA4E;AAC5E,gEAAgE;AAChE,MAAM,oBAAoB,GAAG,EAAE,CAAA;AAE/B;;;;;;;;;GASG;AACI,KAAK,UAAU,mBAAmB,CACvC,GAAa,EACb,UAA4B;IAE5B,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;IACtD,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACnE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAA;IACrB,IAAI,CAAC,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAA;QAChC,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,CAAA;QACvD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;IAC/B,IAAI,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;IAC/B,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IACpB,KAAK,IAAI,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAC/E,0EAA0E;QAC1E,6DAA6D;QAC7D,IAAI,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,IAAI,UAAU,CAC1B,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAC5D,CAAA;YACD,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAA;YACpC,GAAG,GAAG,KAAK,CAAA;QACb,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QAC9B,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,CAAA;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,IAAI,GAAG,GAAG,QAAQ,IAAI,oBAAoB,EAAE,CAAC;YAC3C,QAAQ,GAAG,GAAG,CAAA;YACd,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QAC7B,CAAC;IACH,CAAC;IAED,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAC3B,OAAO,QAAQ,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;AAClE,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { ProgressCallback } from './util.ts';
1
2
  export type BufferEncoding = 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'utf-16le' | 'ucs2' | 'ucs-2' | 'base64' | 'base64url' | 'latin1' | 'binary' | 'hex';
2
3
  export type Fetcher = (input: RequestInfo, init?: RequestInit) => Promise<Response>;
3
4
  export interface FilehandleOptions {
@@ -6,6 +7,13 @@ export interface FilehandleOptions {
6
7
  overrides?: Omit<RequestInit, 'headers'>;
7
8
  encoding?: BufferEncoding;
8
9
  fetch?: Fetcher;
10
+ /**
11
+ * Opt-in download-progress reporting. When set, the response body is streamed
12
+ * and this is called with the running byte count (and Content-Length total
13
+ * when available) as chunks arrive. Omitting it keeps the faster
14
+ * non-streaming read.
15
+ */
16
+ onProgress?: ProgressCallback;
9
17
  }
10
18
  export interface Stats {
11
19
  size: number;
package/esm/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './filehandle.ts';
2
+ export type { ProgressCallback } from './util.ts';
2
3
  export { default as BlobFile } from './blobFile.ts';
3
4
  export { default as RemoteFile } from './remoteFile.ts';
4
5
  export { default as LocalFile } from './localFile.ts';
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAE/B,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAG/B,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
package/esm/remoteFile.js CHANGED
@@ -1,4 +1,4 @@
1
- import { toBytes } from "./util.js";
1
+ import { toBytes, toBytesWithProgress } from "./util.js";
2
2
  function getMessage(e) {
3
3
  const r = typeof e === 'object' &&
4
4
  e !== null &&
@@ -90,7 +90,9 @@ export default class RemoteFile {
90
90
  size: parseInt(sizeMatch[1], 10),
91
91
  };
92
92
  }
93
- const resData = await toBytes(res);
93
+ const resData = opts.onProgress
94
+ ? await toBytesWithProgress(res, opts.onProgress)
95
+ : await toBytes(res);
94
96
  // server didn't honor the range request and returned the full file —
95
97
  // the body length is the actual file size
96
98
  if (!this._stat && res.status === 200) {
@@ -117,6 +119,9 @@ export default class RemoteFile {
117
119
  else if (encoding) {
118
120
  throw new Error(`unsupported encoding: ${encoding}`);
119
121
  }
122
+ else if (opts.onProgress) {
123
+ return toBytesWithProgress(res, opts.onProgress);
124
+ }
120
125
  else {
121
126
  return toBytes(res);
122
127
  }
@@ -1 +1 @@
1
- {"version":3,"file":"remoteFile.js","sourceRoot":"","sources":["../src/remoteFile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remoteFile.js","sourceRoot":"","sources":["../src/remoteFile.ts"],"names":[],"mappings":"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"}
package/esm/util.d.ts CHANGED
@@ -1 +1,14 @@
1
1
  export declare function toBytes(src: Response | Blob): Promise<Uint8Array<ArrayBuffer>>;
2
+ /** Reports bytes downloaded for a single fetch; `total` from Content-Length. */
3
+ export type ProgressCallback = (bytesReceived: number, total?: number) => void;
4
+ /**
5
+ * Read a Response body to bytes while reporting download progress.
6
+ *
7
+ * When Content-Length is known the body is streamed directly into one pre-sized
8
+ * buffer (no per-chunk array, no second copy), ticking `onProgress` as chunks
9
+ * arrive. Without a known length there is no fraction to show, so it falls back
10
+ * to a single one-shot read and one completion tick rather than buffering
11
+ * chunks. Only used when a caller opts in via `onProgress`; the plain {@link
12
+ * toBytes} fast path is unaffected.
13
+ */
14
+ export declare function toBytesWithProgress(res: Response, onProgress: ProgressCallback): Promise<Uint8Array<ArrayBuffer>>;
package/esm/util.js CHANGED
@@ -5,4 +5,50 @@ export async function toBytes(src) {
5
5
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
6
6
  return src.bytes ? src.bytes() : new Uint8Array(await src.arrayBuffer());
7
7
  }
8
+ // throttle intermediate progress ticks; a large body can yield thousands of
9
+ // chunks and the final exact count is always emitted regardless
10
+ const PROGRESS_THROTTLE_MS = 50;
11
+ /**
12
+ * Read a Response body to bytes while reporting download progress.
13
+ *
14
+ * When Content-Length is known the body is streamed directly into one pre-sized
15
+ * buffer (no per-chunk array, no second copy), ticking `onProgress` as chunks
16
+ * arrive. Without a known length there is no fraction to show, so it falls back
17
+ * to a single one-shot read and one completion tick rather than buffering
18
+ * chunks. Only used when a caller opts in via `onProgress`; the plain {@link
19
+ * toBytes} fast path is unaffected.
20
+ */
21
+ export async function toBytesWithProgress(res, onProgress) {
22
+ const lengthHeader = res.headers.get('content-length');
23
+ const total = lengthHeader ? parseInt(lengthHeader, 10) : undefined;
24
+ const body = res.body;
25
+ if (!body || total === undefined) {
26
+ const bytes = await toBytes(res);
27
+ onProgress(bytes.byteLength, total ?? bytes.byteLength);
28
+ return bytes;
29
+ }
30
+ const reader = body.getReader();
31
+ let out = new Uint8Array(total);
32
+ let received = 0;
33
+ let lastTick = 0;
34
+ onProgress(0, total);
35
+ for (let chunk = await reader.read(); !chunk.done; chunk = await reader.read()) {
36
+ // a decoded body can exceed Content-Length (e.g. gzip transfer-encoding);
37
+ // grow the buffer rather than throwing on out.set() overflow
38
+ if (received + chunk.value.byteLength > out.length) {
39
+ const grown = new Uint8Array(Math.max(received + chunk.value.byteLength, out.length * 2));
40
+ grown.set(out.subarray(0, received));
41
+ out = grown;
42
+ }
43
+ out.set(chunk.value, received);
44
+ received += chunk.value.byteLength;
45
+ const now = Date.now();
46
+ if (now - lastTick >= PROGRESS_THROTTLE_MS) {
47
+ lastTick = now;
48
+ onProgress(received, total);
49
+ }
50
+ }
51
+ onProgress(received, total);
52
+ return received === out.length ? out : out.subarray(0, received);
53
+ }
8
54
  //# sourceMappingURL=util.js.map
package/esm/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,+EAA+E;AAC/E,oDAAoD;AACpD,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAoB;IAEpB,uEAAuE;IACvE,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAA;AAC1E,CAAC"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,+EAA+E;AAC/E,oDAAoD;AACpD,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAoB;IAEpB,uEAAuE;IACvE,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAA;AAC1E,CAAC;AAKD,4EAA4E;AAC5E,gEAAgE;AAChE,MAAM,oBAAoB,GAAG,EAAE,CAAA;AAE/B;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAa,EACb,UAA4B;IAE5B,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;IACtD,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACnE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAA;IACrB,IAAI,CAAC,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAA;QAChC,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,CAAA;QACvD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;IAC/B,IAAI,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;IAC/B,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IACpB,KAAK,IAAI,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAC/E,0EAA0E;QAC1E,6DAA6D;QAC7D,IAAI,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,IAAI,UAAU,CAC1B,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAC5D,CAAA;YACD,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAA;YACpC,GAAG,GAAG,KAAK,CAAA;QACb,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QAC9B,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,CAAA;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,IAAI,GAAG,GAAG,QAAQ,IAAI,oBAAoB,EAAE,CAAC;YAC3C,QAAQ,GAAG,GAAG,CAAA;YACd,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QAC7B,CAAC;IACH,CAAC;IAED,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAC3B,OAAO,QAAQ,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;AAClE,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "generic-filehandle2",
3
3
  "description": "uniform interface for accessing binary data from local files, remote HTTP resources, and browser Blob data",
4
- "version": "2.1.10",
4
+ "version": "2.2.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "exports": {
package/src/filehandle.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { ProgressCallback } from './util.ts'
2
+
1
3
  // avoids needing to have @types/node as a dependency of the consuming code
2
4
  export type BufferEncoding =
3
5
  | 'ascii'
@@ -24,6 +26,13 @@ export interface FilehandleOptions {
24
26
  overrides?: Omit<RequestInit, 'headers'>
25
27
  encoding?: BufferEncoding
26
28
  fetch?: Fetcher
29
+ /**
30
+ * Opt-in download-progress reporting. When set, the response body is streamed
31
+ * and this is called with the running byte count (and Content-Length total
32
+ * when available) as chunks arrive. Omitting it keeps the faster
33
+ * non-streaming read.
34
+ */
35
+ onProgress?: ProgressCallback
27
36
  }
28
37
 
29
38
  export interface Stats {
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './filehandle.ts'
2
+ export type { ProgressCallback } from './util.ts'
2
3
 
3
4
  export { default as BlobFile } from './blobFile.ts'
4
5
  export { default as RemoteFile } from './remoteFile.ts'
package/src/remoteFile.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { toBytes } from './util.ts'
1
+ import { toBytes, toBytesWithProgress } from './util.ts'
2
2
 
3
3
  import type {
4
4
  BufferEncoding,
@@ -125,7 +125,9 @@ export default class RemoteFile implements GenericFilehandle {
125
125
  }
126
126
  }
127
127
 
128
- const resData = await toBytes(res)
128
+ const resData = opts.onProgress
129
+ ? await toBytesWithProgress(res, opts.onProgress)
130
+ : await toBytes(res)
129
131
  // server didn't honor the range request and returned the full file —
130
132
  // the body length is the actual file size
131
133
  if (!this._stat && res.status === 200) {
@@ -164,6 +166,8 @@ export default class RemoteFile implements GenericFilehandle {
164
166
  return res.text()
165
167
  } else if (encoding) {
166
168
  throw new Error(`unsupported encoding: ${encoding}`)
169
+ } else if (opts.onProgress) {
170
+ return toBytesWithProgress(res, opts.onProgress)
167
171
  } else {
168
172
  return toBytes(res)
169
173
  }
package/src/util.ts CHANGED
@@ -7,3 +7,61 @@ export async function toBytes(
7
7
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
8
8
  return src.bytes ? src.bytes() : new Uint8Array(await src.arrayBuffer())
9
9
  }
10
+
11
+ /** Reports bytes downloaded for a single fetch; `total` from Content-Length. */
12
+ export type ProgressCallback = (bytesReceived: number, total?: number) => void
13
+
14
+ // throttle intermediate progress ticks; a large body can yield thousands of
15
+ // chunks and the final exact count is always emitted regardless
16
+ const PROGRESS_THROTTLE_MS = 50
17
+
18
+ /**
19
+ * Read a Response body to bytes while reporting download progress.
20
+ *
21
+ * When Content-Length is known the body is streamed directly into one pre-sized
22
+ * buffer (no per-chunk array, no second copy), ticking `onProgress` as chunks
23
+ * arrive. Without a known length there is no fraction to show, so it falls back
24
+ * to a single one-shot read and one completion tick rather than buffering
25
+ * chunks. Only used when a caller opts in via `onProgress`; the plain {@link
26
+ * toBytes} fast path is unaffected.
27
+ */
28
+ export async function toBytesWithProgress(
29
+ res: Response,
30
+ onProgress: ProgressCallback,
31
+ ): Promise<Uint8Array<ArrayBuffer>> {
32
+ const lengthHeader = res.headers.get('content-length')
33
+ const total = lengthHeader ? parseInt(lengthHeader, 10) : undefined
34
+ const body = res.body
35
+ if (!body || total === undefined) {
36
+ const bytes = await toBytes(res)
37
+ onProgress(bytes.byteLength, total ?? bytes.byteLength)
38
+ return bytes
39
+ }
40
+
41
+ const reader = body.getReader()
42
+ let out = new Uint8Array(total)
43
+ let received = 0
44
+ let lastTick = 0
45
+ onProgress(0, total)
46
+ for (let chunk = await reader.read(); !chunk.done; chunk = await reader.read()) {
47
+ // a decoded body can exceed Content-Length (e.g. gzip transfer-encoding);
48
+ // grow the buffer rather than throwing on out.set() overflow
49
+ if (received + chunk.value.byteLength > out.length) {
50
+ const grown = new Uint8Array(
51
+ Math.max(received + chunk.value.byteLength, out.length * 2),
52
+ )
53
+ grown.set(out.subarray(0, received))
54
+ out = grown
55
+ }
56
+ out.set(chunk.value, received)
57
+ received += chunk.value.byteLength
58
+ const now = Date.now()
59
+ if (now - lastTick >= PROGRESS_THROTTLE_MS) {
60
+ lastTick = now
61
+ onProgress(received, total)
62
+ }
63
+ }
64
+
65
+ onProgress(received, total)
66
+ return received === out.length ? out : out.subarray(0, received)
67
+ }