File size: 1,735 Bytes
c212805
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { isStorageError } from '../lib/common/errors'
import { DownloadResult } from '../lib/types'

export default class StreamDownloadBuilder implements Promise<DownloadResult<ReadableStream>> {
  readonly [Symbol.toStringTag]: string = 'StreamDownloadBuilder'
  private promise: Promise<DownloadResult<ReadableStream>> | null = null

  constructor(
    private downloadFn: () => Promise<Response>,
    private shouldThrowOnError: boolean
  ) {}

  then<TResult1 = DownloadResult<ReadableStream>, TResult2 = never>(
    onfulfilled?:
      | ((value: DownloadResult<ReadableStream>) => TResult1 | PromiseLike<TResult1>)
      | null,
    onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
  ): Promise<TResult1 | TResult2> {
    return this.getPromise().then(onfulfilled, onrejected)
  }

  catch<TResult = never>(
    onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
  ): Promise<DownloadResult<ReadableStream> | TResult> {
    return this.getPromise().catch(onrejected)
  }

  finally(onfinally?: (() => void) | null): Promise<DownloadResult<ReadableStream>> {
    return this.getPromise().finally(onfinally)
  }

  private getPromise(): Promise<DownloadResult<ReadableStream>> {
    if (!this.promise) {
      this.promise = this.execute()
    }
    return this.promise
  }

  private async execute(): Promise<DownloadResult<ReadableStream>> {
    try {
      const result = await this.downloadFn()

      return {
        data: result.body as ReadableStream,
        error: null,
      }
    } catch (error) {
      if (this.shouldThrowOnError) {
        throw error
      }

      if (isStorageError(error)) {
        return { data: null, error }
      }

      throw error
    }
  }
}