All files / cli / unstable_progress_bar_stream.ts

100.00% Branches 0/0
100.00% Lines 26/26
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 
 
x3
x3
 
x3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x3
x3
x3
x3
x5
x5
x5
x7
x5
x5
x15
x15
x5
x5
x6
x5
x5
x6
x6
x5
x5
x3





































































// Copyright 2018-2025 the Deno authors. MIT license.

import {
  ProgressBar,
  type ProgressBarOptions,
} from "./unstable_progress_bar.ts";

/**
 * `ProgressBarStream` is a {@link TransformStream} class that reports updates
 * to a separate {@link WritableStream} on a 1s interval.
 *
 * @experimental **UNSTABLE**: New API, yet to be vetted.
 *
 * @example Basic Usage
 * ```ts no-assert
 * import { ProgressBarStream } from "@std/cli/unstable-progress-bar-stream";
 *
 * const response = await fetch("https://example.com/");
 * const max = Number(response.headers.get("content-length"));
 * let readable = response.body
 * if (max) {
 *   readable = readable
 *     ?.pipeThrough(new ProgressBarStream(Deno.stdout.writable, { max })) ?? null;
 * }
 * await readable?.pipeTo((await Deno.create("./_tmp/example.com.html")).writable);
 * ```
 */
export class ProgressBarStream extends TransformStream<Uint8Array, Uint8Array> {
  /**
   * Constructs a new instance.
   *
   * @example Basic Usage
   * ```ts no-assert
   * import { ProgressBarStream } from "@std/cli/unstable-progress-bar-stream";
   *
   * const response = await fetch("https://example.com/");
   * const max = Number(response.headers.get("content-length"));
   * let readable = response.body
   * if (max) {
   *   readable = readable
   *     ?.pipeThrough(new ProgressBarStream(Deno.stdout.writable, { max })) ?? null;
   * }
   * await readable?.pipeTo((await Deno.create("./_tmp/example.com.html")).writable);
   * ```
   *
   * @param writable The {@link WritableStream} that will receive the progress bar
   * reports.
   * @param options The options to configure various settings of the progress bar.
   */
  constructor(
    writable: WritableStream<Uint8Array>,
    options: ProgressBarOptions,
  ) {
    let bar: ProgressBar | undefined;
    super({
      start(_controller) {
        bar = new ProgressBar(writable, options);
      },
      transform(chunk, controller) {
        bar?.add(chunk.length);
        controller.enqueue(chunk);
      },
      flush(_controller) {
        bar?.end();
      },
      cancel() {
        bar?.end();
      },
    });
  }
}