@byloth/core 1.5.0-rc.4 → 1.5.0-rc.6
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.
- package/dist/core.js +459 -161
- package/dist/core.js.map +1 -1
- package/dist/core.umd.cjs +2 -2
- package/dist/core.umd.cjs.map +1 -1
- package/package.json +7 -6
- package/src/core/types.ts +5 -0
- package/src/index.ts +24 -20
- package/src/models/aggregators/aggregated-async-iterator.ts +289 -0
- package/src/models/aggregators/aggregated-iterator.ts +3 -3
- package/src/models/aggregators/aggregator.ts +46 -0
- package/src/models/aggregators/async-aggregator.ts +46 -0
- package/src/models/aggregators/index.ts +4 -47
- package/src/models/aggregators/reduced-iterator.ts +2 -2
- package/src/models/aggregators/types.ts +9 -0
- package/src/models/index.ts +11 -11
- package/src/models/iterators/index.ts +4 -0
- package/src/models/iterators/smart-async-iterator.ts +208 -0
- package/src/models/{smart-iterator.ts → iterators/smart-iterator.ts} +1 -1
- package/src/models/iterators/types.ts +14 -0
- package/src/models/promises/deferred-promise.ts +17 -9
- package/src/models/promises/smart-promise.ts +1 -1
- package/src/models/promises/timed-promise.ts +1 -1
- package/src/models/promises/types.ts +8 -0
- package/src/models/types.ts +22 -0
- package/src/utils/dom.ts +1 -1
- package/src/utils/iterator.ts +11 -0
- package/src/utils/math.ts +6 -1
- package/src/utils/random.ts +14 -10
- package/src/types.ts +0 -21
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import type { AsyncGeneratorFunction, MaybeAsyncIteratee, MaybeAsyncReducer, TypeGuardIteratee } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export default class SmartAsyncIterator<T, R = void, N = undefined> implements AsyncIterator<T, R, N>
|
|
4
|
+
{
|
|
5
|
+
protected _iterator: AsyncIterator<T, R, N>;
|
|
6
|
+
|
|
7
|
+
public return?: (value?: R) => Promise<IteratorResult<T, R>>;
|
|
8
|
+
public throw?: (error?: unknown) => Promise<IteratorResult<T, R>>;
|
|
9
|
+
|
|
10
|
+
public constructor(iterable: AsyncIterable<T>);
|
|
11
|
+
public constructor(iterator: AsyncIterator<T, R, N>);
|
|
12
|
+
public constructor(generatorFn: () => AsyncGenerator<T, R, N>);
|
|
13
|
+
public constructor(argument: AsyncIterable<T> | AsyncIterator<T, R, N> | AsyncGeneratorFunction<T, R, N>);
|
|
14
|
+
public constructor(argument: AsyncIterable<T> | AsyncIterator<T, R, N> | AsyncGeneratorFunction<T, R, N>)
|
|
15
|
+
{
|
|
16
|
+
if (argument instanceof Function)
|
|
17
|
+
{
|
|
18
|
+
this._iterator = argument();
|
|
19
|
+
}
|
|
20
|
+
else if (Symbol.asyncIterator in argument)
|
|
21
|
+
{
|
|
22
|
+
this._iterator = argument[Symbol.asyncIterator]() as AsyncIterator<T, R, N>;
|
|
23
|
+
}
|
|
24
|
+
else
|
|
25
|
+
{
|
|
26
|
+
this._iterator = argument;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (this._iterator.return) { this.return = (value?: R) => this._iterator.return!(value); }
|
|
30
|
+
if (this._iterator.throw) { this.throw = (error?: unknown) => this._iterator.throw!(error); }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public async every(predicate: MaybeAsyncIteratee<T, boolean>): Promise<boolean>
|
|
34
|
+
{
|
|
35
|
+
let index = 0;
|
|
36
|
+
|
|
37
|
+
// eslint-disable-next-line no-constant-condition
|
|
38
|
+
while (true)
|
|
39
|
+
{
|
|
40
|
+
const result = await this._iterator.next();
|
|
41
|
+
|
|
42
|
+
if (result.done) { return true; }
|
|
43
|
+
if (!(predicate(result.value, index))) { return false; }
|
|
44
|
+
|
|
45
|
+
index += 1;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
public async some(predicate: MaybeAsyncIteratee<T, boolean>): Promise<boolean>
|
|
49
|
+
{
|
|
50
|
+
let index = 0;
|
|
51
|
+
|
|
52
|
+
// eslint-disable-next-line no-constant-condition
|
|
53
|
+
while (true)
|
|
54
|
+
{
|
|
55
|
+
const result = await this._iterator.next();
|
|
56
|
+
|
|
57
|
+
if (result.done) { return false; }
|
|
58
|
+
if (predicate(result.value, index)) { return true; }
|
|
59
|
+
|
|
60
|
+
index += 1;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public filter(predicate: MaybeAsyncIteratee<T, boolean>): SmartAsyncIterator<T, R>;
|
|
65
|
+
public filter<S extends T>(predicate: TypeGuardIteratee<T, S>): SmartAsyncIterator<T, S>;
|
|
66
|
+
public filter(predicate: MaybeAsyncIteratee<T, boolean>): SmartAsyncIterator<T, R>
|
|
67
|
+
{
|
|
68
|
+
const iterator = this._iterator;
|
|
69
|
+
|
|
70
|
+
return new SmartAsyncIterator<T, R>(async function* ()
|
|
71
|
+
{
|
|
72
|
+
let index = 0;
|
|
73
|
+
|
|
74
|
+
while (true)
|
|
75
|
+
{
|
|
76
|
+
const result = await iterator.next();
|
|
77
|
+
|
|
78
|
+
if (result.done) { return result.value; }
|
|
79
|
+
if (predicate(result.value, index)) { yield result.value; }
|
|
80
|
+
|
|
81
|
+
index += 1;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
public map<V>(iteratee: MaybeAsyncIteratee<T, V>): SmartAsyncIterator<V, R>
|
|
86
|
+
{
|
|
87
|
+
const iterator = this._iterator;
|
|
88
|
+
|
|
89
|
+
return new SmartAsyncIterator<V, R>(async function* ()
|
|
90
|
+
{
|
|
91
|
+
let index = 0;
|
|
92
|
+
|
|
93
|
+
while (true)
|
|
94
|
+
{
|
|
95
|
+
const result = await iterator.next();
|
|
96
|
+
if (result.done) { return result.value; }
|
|
97
|
+
|
|
98
|
+
yield iteratee(result.value, index);
|
|
99
|
+
|
|
100
|
+
index += 1;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
public async reduce(reducer: MaybeAsyncReducer<T, T>): Promise<T>;
|
|
105
|
+
public async reduce<A>(reducer: MaybeAsyncReducer<T, A>, initialValue: A): Promise<A>;
|
|
106
|
+
public async reduce<A>(reducer: MaybeAsyncReducer<T, A>, initialValue?: A): Promise<A>
|
|
107
|
+
{
|
|
108
|
+
let index = 0;
|
|
109
|
+
let accumulator = initialValue;
|
|
110
|
+
if (accumulator === undefined)
|
|
111
|
+
{
|
|
112
|
+
const result = await this._iterator.next();
|
|
113
|
+
if (result.done) { throw new TypeError("Reduce of empty iterator with no initial value"); }
|
|
114
|
+
|
|
115
|
+
accumulator = (result.value as unknown) as A;
|
|
116
|
+
index += 1;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// eslint-disable-next-line no-constant-condition
|
|
120
|
+
while (true)
|
|
121
|
+
{
|
|
122
|
+
const result = await this._iterator.next();
|
|
123
|
+
if (result.done) { return accumulator; }
|
|
124
|
+
|
|
125
|
+
accumulator = await reducer(accumulator, result.value, index);
|
|
126
|
+
|
|
127
|
+
index += 1;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public enumerate(): SmartAsyncIterator<[number, T], R>
|
|
132
|
+
{
|
|
133
|
+
return this.map((value, index) => [index, value]);
|
|
134
|
+
}
|
|
135
|
+
public unique(): SmartAsyncIterator<T, R>
|
|
136
|
+
{
|
|
137
|
+
const iterator = this._iterator;
|
|
138
|
+
|
|
139
|
+
return new SmartAsyncIterator<T, R>(async function* ()
|
|
140
|
+
{
|
|
141
|
+
const values = new Set<T>();
|
|
142
|
+
|
|
143
|
+
while (true)
|
|
144
|
+
{
|
|
145
|
+
const result = await iterator.next();
|
|
146
|
+
|
|
147
|
+
if (result.done) { return result.value; }
|
|
148
|
+
if (values.has(result.value)) { continue; }
|
|
149
|
+
|
|
150
|
+
values.add(result.value);
|
|
151
|
+
|
|
152
|
+
yield result.value;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
public async count(): Promise<number>
|
|
158
|
+
{
|
|
159
|
+
let index = 0;
|
|
160
|
+
|
|
161
|
+
// eslint-disable-next-line no-constant-condition
|
|
162
|
+
while (true)
|
|
163
|
+
{
|
|
164
|
+
const result = await this._iterator.next();
|
|
165
|
+
if (result.done) { return index; }
|
|
166
|
+
|
|
167
|
+
index += 1;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
public async forEach(iteratee: MaybeAsyncIteratee<T>): Promise<void>
|
|
171
|
+
{
|
|
172
|
+
let index = 0;
|
|
173
|
+
|
|
174
|
+
// eslint-disable-next-line no-constant-condition
|
|
175
|
+
while (true)
|
|
176
|
+
{
|
|
177
|
+
const result = await this._iterator.next();
|
|
178
|
+
if (result.done) { return; }
|
|
179
|
+
|
|
180
|
+
await iteratee(result.value, index);
|
|
181
|
+
|
|
182
|
+
index += 1;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
public next(...values: N extends undefined ? [] : [N]): Promise<IteratorResult<T, R>>
|
|
187
|
+
{
|
|
188
|
+
return this._iterator.next(...values);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
public async toArray(): Promise<T[]>
|
|
192
|
+
{
|
|
193
|
+
const elements: T[] = [];
|
|
194
|
+
|
|
195
|
+
// eslint-disable-next-line no-constant-condition
|
|
196
|
+
while (true)
|
|
197
|
+
{
|
|
198
|
+
const result = await this._iterator.next();
|
|
199
|
+
if (result.done) { return elements; }
|
|
200
|
+
|
|
201
|
+
elements.push(result.value);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
public get [Symbol.toStringTag]() { return "SmartAsyncIterator"; }
|
|
206
|
+
|
|
207
|
+
public [Symbol.asyncIterator](): SmartAsyncIterator<T, R, N> { return this; }
|
|
208
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GeneratorFunction, Iteratee, TypeGuardIteratee, Reducer } from "
|
|
1
|
+
import type { GeneratorFunction, Iteratee, TypeGuardIteratee, Reducer } from "./types.js";
|
|
2
2
|
|
|
3
3
|
export default class SmartIterator<T, R = void, N = undefined> implements Iterator<T, R, N>
|
|
4
4
|
{
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MaybePromise } from "../promises/types.js";
|
|
2
|
+
|
|
3
|
+
export type GeneratorFunction<T, R = void, N = undefined> = () => Generator<T, R, N>;
|
|
4
|
+
export type AsyncGeneratorFunction<T, R = void, N = undefined> = () => AsyncGenerator<T, R, N>;
|
|
5
|
+
|
|
6
|
+
export type Iteratee<T, R = void> = (value: T, index: number) => R;
|
|
7
|
+
export type MaybeAsyncIteratee<T, R = void> = (value: T, index: number) => MaybePromise<R>;
|
|
8
|
+
|
|
9
|
+
export type TypeGuardIteratee<T, R extends T> = (value: T, index: number) => value is R;
|
|
10
|
+
export type MaybeAsyncTypeGuardIteratee<T, R extends T> = (value: MaybePromise<T>, index: number) =>
|
|
11
|
+
value is MaybePromise<R>;
|
|
12
|
+
|
|
13
|
+
export type Reducer<T, A> = (accumulator: A, value: T, index: number) => A;
|
|
14
|
+
export type MaybeAsyncReducer<T, A> = (accumulator: A, value: T, index: number) => MaybePromise<A>;
|
|
@@ -1,30 +1,38 @@
|
|
|
1
|
-
import type { PromiseResolver, PromiseRejecter, FulfilledHandler, RejectedHandler } from "
|
|
1
|
+
import type { PromiseResolver, PromiseRejecter, FulfilledHandler, RejectedHandler } from "./types.js";
|
|
2
2
|
|
|
3
3
|
import SmartPromise from "./smart-promise.js";
|
|
4
4
|
|
|
5
5
|
export default class DeferredPromise<T = void, F = T, R = never> extends SmartPromise<F | R>
|
|
6
6
|
{
|
|
7
|
-
protected _resolve
|
|
8
|
-
protected _reject
|
|
7
|
+
protected _resolve: PromiseResolver<T>;
|
|
8
|
+
protected _reject: PromiseRejecter;
|
|
9
9
|
|
|
10
10
|
public constructor(onFulfilled?: FulfilledHandler<T, F> | null, onRejected?: RejectedHandler<unknown, R> | null)
|
|
11
11
|
{
|
|
12
|
+
let _resolve: PromiseResolver<T>;
|
|
13
|
+
let _reject: PromiseRejecter;
|
|
14
|
+
|
|
12
15
|
super((resolve, reject) =>
|
|
13
16
|
{
|
|
14
|
-
|
|
15
|
-
this
|
|
17
|
+
// ReferenceError: Must call super constructor in derived class before accessing
|
|
18
|
+
// 'this' or returning from derived constructor.
|
|
19
|
+
//
|
|
20
|
+
_resolve = resolve as PromiseResolver<T>;
|
|
21
|
+
_reject = reject;
|
|
16
22
|
});
|
|
17
23
|
|
|
18
|
-
this._promise
|
|
19
|
-
|
|
24
|
+
this._promise.then(onFulfilled as FulfilledHandler<F | R>, onRejected);
|
|
25
|
+
|
|
26
|
+
this._resolve = _resolve!;
|
|
27
|
+
this._reject = _reject!;
|
|
20
28
|
}
|
|
21
29
|
|
|
22
30
|
public get resolve(): PromiseResolver<T> { return this._resolve; }
|
|
23
31
|
public get reject(): PromiseRejecter { return this._reject; }
|
|
24
32
|
|
|
25
|
-
public watch(
|
|
33
|
+
public watch(otherPromise: PromiseLike<T>): this
|
|
26
34
|
{
|
|
27
|
-
|
|
35
|
+
otherPromise.then(this.resolve, this.reject);
|
|
28
36
|
|
|
29
37
|
return this;
|
|
30
38
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { MaybePromise, PromiseExecutor } from "../../types.js";
|
|
2
1
|
import { TimeoutException } from "../exceptions/index.js";
|
|
3
2
|
|
|
4
3
|
import SmartPromise from "./smart-promise.js";
|
|
4
|
+
import type { MaybePromise, PromiseExecutor } from "./types.js";
|
|
5
5
|
|
|
6
6
|
export default class TimedPromise<T = void> extends SmartPromise<T>
|
|
7
7
|
{
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type MaybePromise<T> = T | PromiseLike<T>;
|
|
2
|
+
|
|
3
|
+
export type FulfilledHandler<T = void, R = T> = (value: T) => MaybePromise<R>;
|
|
4
|
+
export type RejectedHandler<E = unknown, R = never> = (reason: E) => MaybePromise<R>;
|
|
5
|
+
|
|
6
|
+
export type PromiseResolver<T = void> = (result: MaybePromise<T>) => void;
|
|
7
|
+
export type PromiseRejecter<E = unknown> = (reason?: MaybePromise<E>) => void;
|
|
8
|
+
export type PromiseExecutor<T = void, E = unknown> = (resolve: PromiseResolver<T>, reject: PromiseRejecter<E>) => void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type { KeyIteratee, KeyReducer, KeyTypeGuardIteratee } from "./aggregators/types.js";
|
|
2
|
+
export type {
|
|
3
|
+
GeneratorFunction,
|
|
4
|
+
AsyncGeneratorFunction,
|
|
5
|
+
Iteratee,
|
|
6
|
+
MaybeAsyncIteratee,
|
|
7
|
+
TypeGuardIteratee,
|
|
8
|
+
MaybeAsyncTypeGuardIteratee,
|
|
9
|
+
Reducer,
|
|
10
|
+
MaybeAsyncReducer
|
|
11
|
+
|
|
12
|
+
} from "./iterators/types.js";
|
|
13
|
+
|
|
14
|
+
export type {
|
|
15
|
+
MaybePromise,
|
|
16
|
+
FulfilledHandler,
|
|
17
|
+
RejectedHandler,
|
|
18
|
+
PromiseResolver,
|
|
19
|
+
PromiseRejecter,
|
|
20
|
+
PromiseExecutor
|
|
21
|
+
|
|
22
|
+
} from "./promises/types.js";
|
package/src/utils/dom.ts
CHANGED
package/src/utils/iterator.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { SmartIterator } from "../models/index.js";
|
|
2
2
|
|
|
3
|
+
export function chain<T>(...iterables: Iterable<T>[]): SmartIterator<T>
|
|
4
|
+
{
|
|
5
|
+
return new SmartIterator<T>(function* ()
|
|
6
|
+
{
|
|
7
|
+
for (const iterable of iterables)
|
|
8
|
+
{
|
|
9
|
+
for (const element of iterable) { yield element; }
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
3
14
|
export function count<T>(elements: Iterable<T>): number
|
|
4
15
|
{
|
|
5
16
|
if (Array.isArray(elements)) { return elements.length; }
|
package/src/utils/math.ts
CHANGED
|
@@ -27,13 +27,18 @@ export function average<T extends number>(values: Iterable<T>, weights?: Iterabl
|
|
|
27
27
|
|
|
28
28
|
for (const [value, weight] of zip(values, weights))
|
|
29
29
|
{
|
|
30
|
+
if (weight <= 0)
|
|
31
|
+
{
|
|
32
|
+
throw new ValueException(`The weight for the value #${_index} must be greater than zero.`);
|
|
33
|
+
}
|
|
34
|
+
|
|
30
35
|
_sum += value * weight;
|
|
31
36
|
_count += weight;
|
|
32
37
|
_index += 1;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
if (_index === 0) { throw new ValueException("You must provide at least one value and weight."); }
|
|
36
|
-
if (_count
|
|
41
|
+
if (_count > 0) { throw new ValueException("The sum of weights must be greater than zero."); }
|
|
37
42
|
|
|
38
43
|
return _sum / _count;
|
|
39
44
|
}
|
package/src/utils/random.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ValueException } from "../models/index.js";
|
|
2
|
+
|
|
1
3
|
export default class Random
|
|
2
4
|
{
|
|
3
5
|
public static Boolean(ratio: number = 0.5): boolean
|
|
@@ -9,29 +11,31 @@ export default class Random
|
|
|
9
11
|
public static Integer(min: number, max: number): number;
|
|
10
12
|
public static Integer(min: number, max?: number): number
|
|
11
13
|
{
|
|
12
|
-
if (max === undefined)
|
|
13
|
-
{
|
|
14
|
-
return Math.floor(Math.random() * min);
|
|
15
|
-
}
|
|
14
|
+
if (max === undefined) { return Math.floor(Math.random() * min); }
|
|
16
15
|
|
|
17
16
|
return Math.floor(Math.random() * (max - min) + min);
|
|
18
17
|
}
|
|
19
18
|
|
|
19
|
+
public static Decimal(): number;
|
|
20
20
|
public static Decimal(max: number): number;
|
|
21
21
|
public static Decimal(min: number, max: number): number;
|
|
22
|
-
public static Decimal(min
|
|
22
|
+
public static Decimal(min?: number, max?: number): number
|
|
23
23
|
{
|
|
24
|
-
if (
|
|
25
|
-
{
|
|
26
|
-
return (Math.random() * min);
|
|
27
|
-
}
|
|
24
|
+
if (min === undefined) { return Math.random(); }
|
|
25
|
+
if (max === undefined) { return (Math.random() * min); }
|
|
28
26
|
|
|
29
27
|
return (Math.random() * (max - min) + min);
|
|
30
28
|
}
|
|
31
29
|
|
|
30
|
+
public static Index<T>(elements: T[]): number
|
|
31
|
+
{
|
|
32
|
+
if (elements.length === 0) { throw new ValueException("You must provide at least one element."); }
|
|
33
|
+
|
|
34
|
+
return this.Integer(elements.length);
|
|
35
|
+
}
|
|
32
36
|
public static Choice<T>(elements: T[]): T
|
|
33
37
|
{
|
|
34
|
-
return elements[
|
|
38
|
+
return elements[Random.Index(elements)];
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
// eslint-disable-next-line no-useless-constructor
|
package/src/types.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2
|
-
export type Constructor<T extends object, P extends unknown[] = any[]> = new (...args: P) => T;
|
|
3
|
-
|
|
4
|
-
export type GeneratorFunction<T, R = void, N = undefined> = () => Generator<T, R, N>;
|
|
5
|
-
export type AsyncGeneratorFunction<T, R = void, N = undefined> = () => AsyncGenerator<T, R, N>;
|
|
6
|
-
export type Iteratee<T, R = void> = (value: T, index: number) => R;
|
|
7
|
-
export type TypeGuardIteratee<T, R extends T> = (value: T, index: number) => value is R;
|
|
8
|
-
|
|
9
|
-
export type Reducer<T, A> = (accumulator: A, value: T, index: number) => A;
|
|
10
|
-
|
|
11
|
-
export type MaybePromise<T> = T | PromiseLike<T>;
|
|
12
|
-
|
|
13
|
-
export type FulfilledHandler<T = void, R = T> = (value: T) => MaybePromise<R>;
|
|
14
|
-
export type RejectedHandler<E = unknown, R = never> = (reason: E) => MaybePromise<R>;
|
|
15
|
-
|
|
16
|
-
export type PromiseResolver<T = void> = (result: MaybePromise<T>) => void;
|
|
17
|
-
export type PromiseRejecter<E = unknown> = (reason?: MaybePromise<E>) => void;
|
|
18
|
-
export type PromiseExecutor<T = void, E = unknown> = (resolve: PromiseResolver<T>, reject: PromiseRejecter<E>) => void;
|
|
19
|
-
|
|
20
|
-
export type Interval = ReturnType<typeof setInterval>;
|
|
21
|
-
export type Timeout = ReturnType<typeof setTimeout>;
|