1 | import { constraint, round } from '@aryth/math'
|
2 | import { valid } from '@typen/nullish'
|
3 | import { ETA } from '../util/ETA.js'
|
4 | import { pad3 } from '../util/humanScale.js'
|
5 |
|
6 | export class State {
|
7 | constructor(data) {
|
8 | this.value = data.value ?? 0
|
9 | this.total = data.total ?? 100
|
10 | this.start = data.start ?? Date.now()
|
11 | this.end = data.end ?? null
|
12 | this.calETA = data.eta
|
13 | ? new ETA(data.eta.capacity ?? 64, this.start, this.value)
|
14 | : null
|
15 | return this
|
16 | }
|
17 |
|
18 | static build(data) { return new State(data) }
|
19 |
|
20 | get eta() { return this.calETA?.estimate }
|
21 |
|
22 | get reachLimit() { return this.value >= this.total }
|
23 |
|
24 | get elapsed() { return round(( ( this.end ?? Date.now() ) - this.start ) / 1000) }
|
25 |
|
26 | get percent() { return pad3('' + ~~( this.progress * 100 )) }
|
27 |
|
28 | get progress() {
|
29 | const progress = ( this.value / this.total )
|
30 | return isNaN(progress)
|
31 | ? 0
|
32 | : constraint(progress, 0, 1)
|
33 | }
|
34 |
|
35 | update(value) {
|
36 | if (valid(value)) this.value = value
|
37 | this.now = Date.now()
|
38 | this.calETA?.update(this)
|
39 | if (this.reachLimit) this.end = this.now
|
40 | return this
|
41 | }
|
42 |
|
43 | stop(value) {
|
44 | if (valid(value)) this.value = value
|
45 | this.end = Date.now()
|
46 | return this
|
47 | }
|
48 | } |
\ | No newline at end of file |