generated from antfu/starter-ts
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathidleValue.ts
66 lines (59 loc) · 1.55 KB
/
idleValue.ts
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
import { cIC, rIC } from './idleCbWithPolyfill'
/**
* A class that wraps a value that is initialized when idle.
*/
export class IdleValue<T, TInitFunc extends () => T> {
private init_: TInitFunc
private value_?: T
private idleHandle_?: number
initialized: boolean = false
/**
* Accepts a function to initialize the value of a variable when idle.
*/
constructor(init: TInitFunc) {
if (typeof init !== 'function')
throw new TypeError('init must be a function')
this.init_ = init
this.idleHandle_ = rIC(async () => {
try {
this.value_ = this.init_()
this.initialized = true
}
catch (error) {
console.error('Error initializing value:', error)
}
})
}
/**
* Returns the value if it's already been initialized. If it hasn't then the
* initializer function is run immediately and the pending idle callback
* is cancelled.
*/
getValue(): T {
if (!this.initialized) {
this.cancelIdleInit_()
try {
this.value_ = this.init_()
this.initialized = true
}
catch (error) {
console.error('Error getting value:', error)
}
}
return this.value_! // Assert non-null value
}
setValue(newValue: T): void {
this.cancelIdleInit_()
this.value_ = newValue
this.initialized = true
}
/**
* Cancels any scheduled requestIdleCallback and resets the handle.
*/
private cancelIdleInit_(): void {
if (this.idleHandle_ !== undefined) {
cIC(this.idleHandle_)
this.idleHandle_ = undefined
}
}
}