@byloth/core 1.5.3 → 2.0.0-rc.10
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 +1468 -826
- package/dist/core.js.map +1 -1
- package/dist/core.umd.cjs +3 -3
- package/dist/core.umd.cjs.map +1 -1
- package/package.json +8 -10
- package/src/helpers.ts +10 -0
- package/src/index.ts +33 -16
- package/src/models/aggregators/aggregated-async-iterator.ts +129 -81
- package/src/models/aggregators/aggregated-iterator.ts +128 -82
- package/src/models/aggregators/index.ts +1 -3
- package/src/models/aggregators/reduced-iterator.ts +119 -31
- package/src/models/aggregators/types.ts +15 -10
- package/src/models/callbacks/callable-object.ts +23 -0
- package/src/models/callbacks/index.ts +5 -0
- package/src/models/callbacks/publisher.ts +45 -0
- package/src/models/callbacks/switchable-callback.ts +108 -0
- package/src/models/callbacks/types.ts +1 -0
- package/src/models/exceptions/core.ts +6 -7
- package/src/models/exceptions/index.ts +50 -10
- package/src/models/game-loop.ts +83 -0
- package/src/models/index.ts +10 -7
- package/src/models/iterators/smart-async-iterator.ts +112 -24
- package/src/models/iterators/smart-iterator.ts +108 -13
- package/src/models/iterators/types.ts +17 -7
- package/src/models/json/index.ts +3 -0
- package/src/models/{json-storage.ts → json/json-storage.ts} +40 -28
- package/src/models/json/types.ts +5 -0
- package/src/models/promises/deferred-promise.ts +1 -1
- package/src/models/promises/index.ts +3 -1
- package/src/models/promises/long-running-task.ts +294 -0
- package/src/models/promises/smart-promise.ts +6 -1
- package/src/models/promises/thenable.ts +97 -0
- package/src/models/promises/timed-promise.ts +1 -1
- package/src/models/promises/types.ts +2 -0
- package/src/models/timers/clock.ts +69 -0
- package/src/models/timers/countdown.ts +117 -0
- package/src/models/timers/index.ts +4 -0
- package/src/models/types.ts +20 -9
- package/src/utils/async.ts +9 -4
- package/src/utils/date.ts +7 -4
- package/src/utils/index.ts +2 -2
- package/src/utils/random.ts +4 -3
- package/src/models/aggregators/aggregator.ts +0 -46
- package/src/models/aggregators/async-aggregator.ts +0 -56
- package/src/models/subscribers.ts +0 -35
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { KeyException, NotImplementedException, RuntimeException } from "../exceptions/index.js";
|
|
2
|
+
|
|
3
|
+
import CallableObject from "./callable-object.js";
|
|
4
|
+
import type { Callback } from "./types.js";
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
|
+
export default class SwitchableCallback<T extends Callback<any[], any> = Callback> extends CallableObject<T>
|
|
8
|
+
{
|
|
9
|
+
protected _callback: T;
|
|
10
|
+
protected _callbacks: Map<string, T>;
|
|
11
|
+
|
|
12
|
+
protected _isEnabled: boolean;
|
|
13
|
+
public get isEnabled(): boolean { return this._isEnabled; }
|
|
14
|
+
|
|
15
|
+
protected _key: string;
|
|
16
|
+
public get key(): string { return this._key; }
|
|
17
|
+
|
|
18
|
+
public readonly invoke: (...args: Parameters<T>) => ReturnType<T>;
|
|
19
|
+
|
|
20
|
+
public constructor()
|
|
21
|
+
{
|
|
22
|
+
const _default = () =>
|
|
23
|
+
{
|
|
24
|
+
throw new NotImplementedException(
|
|
25
|
+
"The `SwitchableCallback` has no callback defined yet. " +
|
|
26
|
+
"Did you forget to call the `register` method?"
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
super();
|
|
31
|
+
|
|
32
|
+
this._callback = ((_default) as unknown) as T;
|
|
33
|
+
this._callbacks = new Map<string, T>();
|
|
34
|
+
|
|
35
|
+
this._isEnabled = true;
|
|
36
|
+
this._key = "";
|
|
37
|
+
|
|
38
|
+
this.invoke = (...args: Parameters<T>): ReturnType<T> => this._callback(...args);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public enable(): void
|
|
42
|
+
{
|
|
43
|
+
if (!(this._key))
|
|
44
|
+
{
|
|
45
|
+
throw new KeyException(
|
|
46
|
+
"The `SwitchableCallback` has no callback defined yet. " +
|
|
47
|
+
"Did you forget to call the `register` method?"
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
if (this._isEnabled)
|
|
51
|
+
{
|
|
52
|
+
throw new RuntimeException("The `SwitchableCallback` is already enabled.");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this._callback = this._callbacks.get(this._key)!;
|
|
56
|
+
this._isEnabled = true;
|
|
57
|
+
}
|
|
58
|
+
public disable(): void
|
|
59
|
+
{
|
|
60
|
+
if (!(this._isEnabled))
|
|
61
|
+
{
|
|
62
|
+
throw new RuntimeException("The `SwitchableCallback` is already disabled.");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
66
|
+
this._callback = (() => { }) as T;
|
|
67
|
+
this._isEnabled = false;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public register(key: string, callback: T): void
|
|
71
|
+
{
|
|
72
|
+
if (this._callbacks.size === 0)
|
|
73
|
+
{
|
|
74
|
+
this._key = key;
|
|
75
|
+
this._callback = callback;
|
|
76
|
+
}
|
|
77
|
+
else if (this._callbacks.has(key))
|
|
78
|
+
{
|
|
79
|
+
throw new KeyException(`The key '${key}' has already been used for another callback.`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
this._callbacks.set(key, callback);
|
|
83
|
+
}
|
|
84
|
+
public unregister(key: string): void
|
|
85
|
+
{
|
|
86
|
+
if (!(this._callbacks.has(key)))
|
|
87
|
+
{
|
|
88
|
+
throw new KeyException(`The key '${key}' doesn't yet have any associated callback.`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
this._callbacks.delete(key);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public switch(key: string): void
|
|
95
|
+
{
|
|
96
|
+
if (!(this._callbacks.has(key)))
|
|
97
|
+
{
|
|
98
|
+
throw new KeyException(`The key '${key}' doesn't yet have any associated callback.`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this._key = key;
|
|
102
|
+
|
|
103
|
+
if (this._isEnabled)
|
|
104
|
+
{
|
|
105
|
+
this._callback = this._callbacks.get(key)!;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Callback<A extends unknown[] = [], R = void> = (...args: A) => R;
|
|
@@ -39,7 +39,7 @@ export default class Exception extends Error
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
public
|
|
42
|
+
public readonly [Symbol.toStringTag]: string = "Exception";
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export class FatalErrorException extends Exception
|
|
@@ -48,17 +48,16 @@ export class FatalErrorException extends Exception
|
|
|
48
48
|
{
|
|
49
49
|
if (message === undefined)
|
|
50
50
|
{
|
|
51
|
-
message = "The
|
|
52
|
-
"Please,
|
|
51
|
+
message = "The program has encountered an unrecoverable error and cannot continue as expected. " +
|
|
52
|
+
"Please, try again later. If the problem persists, contact the support team.";
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
super(message, cause, name);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
public
|
|
58
|
+
public readonly [Symbol.toStringTag]: string = "FatalErrorException";
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
export class NotImplementedException extends Exception
|
|
60
|
+
export class NotImplementedException extends FatalErrorException
|
|
62
61
|
{
|
|
63
62
|
public constructor(message?: string, cause?: unknown, name = "NotImplementedException")
|
|
64
63
|
{
|
|
@@ -70,5 +69,5 @@ export class NotImplementedException extends Exception
|
|
|
70
69
|
super(message, cause, name);
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
public
|
|
72
|
+
public readonly [Symbol.toStringTag]: string = "NotImplementedException";
|
|
74
73
|
}
|
|
@@ -1,14 +1,33 @@
|
|
|
1
1
|
import Exception from "./core.js";
|
|
2
2
|
|
|
3
|
-
export class
|
|
3
|
+
export class FileException extends Exception
|
|
4
|
+
{
|
|
5
|
+
public constructor(message: string, cause?: unknown, name = "FileException")
|
|
6
|
+
{
|
|
7
|
+
super(message, cause, name);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
public readonly [Symbol.toStringTag]: string = "FileException";
|
|
11
|
+
}
|
|
12
|
+
export class FileExistsException extends FileException
|
|
13
|
+
{
|
|
14
|
+
public constructor(message: string, cause?: unknown, name = "FileExistsException")
|
|
15
|
+
{
|
|
16
|
+
super(message, cause, name);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public readonly [Symbol.toStringTag]: string = "FileExistsException";
|
|
20
|
+
}
|
|
21
|
+
export class FileNotFoundException extends FileException
|
|
4
22
|
{
|
|
5
23
|
public constructor(message: string, cause?: unknown, name = "FileNotFoundException")
|
|
6
24
|
{
|
|
7
25
|
super(message, cause, name);
|
|
8
26
|
}
|
|
9
27
|
|
|
10
|
-
public
|
|
28
|
+
public readonly [Symbol.toStringTag]: string = "FileNotFoundException";
|
|
11
29
|
}
|
|
30
|
+
|
|
12
31
|
export class KeyException extends Exception
|
|
13
32
|
{
|
|
14
33
|
public constructor(message: string, cause?: unknown, name = "KeyException")
|
|
@@ -16,7 +35,7 @@ export class KeyException extends Exception
|
|
|
16
35
|
super(message, cause, name);
|
|
17
36
|
}
|
|
18
37
|
|
|
19
|
-
public
|
|
38
|
+
public readonly [Symbol.toStringTag]: string = "KeyException";
|
|
20
39
|
}
|
|
21
40
|
export class NetworkException extends Exception
|
|
22
41
|
{
|
|
@@ -25,7 +44,7 @@ export class NetworkException extends Exception
|
|
|
25
44
|
super(message, cause, name);
|
|
26
45
|
}
|
|
27
46
|
|
|
28
|
-
public
|
|
47
|
+
public readonly [Symbol.toStringTag]: string = "NetworkException";
|
|
29
48
|
}
|
|
30
49
|
export class PermissionException extends Exception
|
|
31
50
|
{
|
|
@@ -34,7 +53,7 @@ export class PermissionException extends Exception
|
|
|
34
53
|
super(message, cause, name);
|
|
35
54
|
}
|
|
36
55
|
|
|
37
|
-
public
|
|
56
|
+
public readonly [Symbol.toStringTag]: string = "PermissionException";
|
|
38
57
|
}
|
|
39
58
|
export class ReferenceException extends Exception
|
|
40
59
|
{
|
|
@@ -43,8 +62,9 @@ export class ReferenceException extends Exception
|
|
|
43
62
|
super(message, cause, name);
|
|
44
63
|
}
|
|
45
64
|
|
|
46
|
-
public
|
|
65
|
+
public readonly [Symbol.toStringTag]: string = "ReferenceException";
|
|
47
66
|
}
|
|
67
|
+
|
|
48
68
|
export class RuntimeException extends Exception
|
|
49
69
|
{
|
|
50
70
|
public constructor(message: string, cause?: unknown, name = "RuntimeException")
|
|
@@ -52,8 +72,18 @@ export class RuntimeException extends Exception
|
|
|
52
72
|
super(message, cause, name);
|
|
53
73
|
}
|
|
54
74
|
|
|
55
|
-
public
|
|
75
|
+
public readonly [Symbol.toStringTag]: string = "RuntimeException";
|
|
56
76
|
}
|
|
77
|
+
export class EnvironmentException extends RuntimeException
|
|
78
|
+
{
|
|
79
|
+
public constructor(message: string, cause?: unknown, name = "EnvironmentException")
|
|
80
|
+
{
|
|
81
|
+
super(message, cause, name);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public readonly [Symbol.toStringTag]: string = "EnvironmentException";
|
|
85
|
+
}
|
|
86
|
+
|
|
57
87
|
export class TimeoutException extends Exception
|
|
58
88
|
{
|
|
59
89
|
public constructor(message: string, cause?: unknown, name = "TimeoutException")
|
|
@@ -61,7 +91,7 @@ export class TimeoutException extends Exception
|
|
|
61
91
|
super(message, cause, name);
|
|
62
92
|
}
|
|
63
93
|
|
|
64
|
-
public
|
|
94
|
+
public readonly [Symbol.toStringTag]: string = "TimeoutException";
|
|
65
95
|
}
|
|
66
96
|
export class TypeException extends Exception
|
|
67
97
|
{
|
|
@@ -70,8 +100,9 @@ export class TypeException extends Exception
|
|
|
70
100
|
super(message, cause, name);
|
|
71
101
|
}
|
|
72
102
|
|
|
73
|
-
public
|
|
103
|
+
public readonly [Symbol.toStringTag]: string = "TypeException";
|
|
74
104
|
}
|
|
105
|
+
|
|
75
106
|
export class ValueException extends Exception
|
|
76
107
|
{
|
|
77
108
|
public constructor(message: string, cause?: unknown, name = "ValueException")
|
|
@@ -79,7 +110,16 @@ export class ValueException extends Exception
|
|
|
79
110
|
super(message, cause, name);
|
|
80
111
|
}
|
|
81
112
|
|
|
82
|
-
public
|
|
113
|
+
public readonly [Symbol.toStringTag]: string = "ValueException";
|
|
114
|
+
}
|
|
115
|
+
export class RangeException extends ValueException
|
|
116
|
+
{
|
|
117
|
+
public constructor(message: string, cause?: unknown, name = "RangeException")
|
|
118
|
+
{
|
|
119
|
+
super(message, cause, name);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public readonly [Symbol.toStringTag]: string = "RangeException";
|
|
83
123
|
}
|
|
84
124
|
|
|
85
125
|
export { Exception };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Interval } from "../core/types.js";
|
|
2
|
+
import { isBrowser } from "../helpers.js";
|
|
3
|
+
|
|
4
|
+
import { FatalErrorException, RuntimeException } from "./exceptions/index.js";
|
|
5
|
+
|
|
6
|
+
export default class GameLoop
|
|
7
|
+
{
|
|
8
|
+
protected _handle?: number | Interval;
|
|
9
|
+
|
|
10
|
+
protected _startTime: number;
|
|
11
|
+
public get startTime(): number
|
|
12
|
+
{
|
|
13
|
+
return this._startTime;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
protected _isRunning: boolean;
|
|
17
|
+
public get isRunning(): boolean
|
|
18
|
+
{
|
|
19
|
+
return this._isRunning;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public get elapsedTime(): number
|
|
23
|
+
{
|
|
24
|
+
return performance.now() - this._startTime;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
protected _start: () => void;
|
|
28
|
+
protected _stop: () => void;
|
|
29
|
+
|
|
30
|
+
public constructor(callback: FrameRequestCallback, msIfNotBrowser = 40)
|
|
31
|
+
{
|
|
32
|
+
this._startTime = 0;
|
|
33
|
+
this._isRunning = false;
|
|
34
|
+
|
|
35
|
+
if (isBrowser)
|
|
36
|
+
{
|
|
37
|
+
this._start = () =>
|
|
38
|
+
{
|
|
39
|
+
callback(this.elapsedTime);
|
|
40
|
+
|
|
41
|
+
this._handle = window.requestAnimationFrame(this._start);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
this._stop = () => window.cancelAnimationFrame(this._handle as number);
|
|
45
|
+
}
|
|
46
|
+
else
|
|
47
|
+
{
|
|
48
|
+
// eslint-disable-next-line no-console
|
|
49
|
+
console.warn(
|
|
50
|
+
"Not a browser environment detected. " +
|
|
51
|
+
`Using setInterval@${msIfNotBrowser}ms instead of requestAnimationFrame...`
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
this._start = () =>
|
|
55
|
+
{
|
|
56
|
+
this._handle = setInterval(() => callback(this.elapsedTime), msIfNotBrowser);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
this._stop = () => clearInterval(this._handle as Interval);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public start(elapsedTime = 0): void
|
|
64
|
+
{
|
|
65
|
+
if (this._isRunning) { throw new RuntimeException("The game loop has already been started."); }
|
|
66
|
+
|
|
67
|
+
this._startTime = performance.now() - elapsedTime;
|
|
68
|
+
this._start();
|
|
69
|
+
this._isRunning = true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public stop(): void
|
|
73
|
+
{
|
|
74
|
+
if (!(this._isRunning)) { throw new RuntimeException("The game loop hadn't yet started."); }
|
|
75
|
+
if (!(this._handle)) { throw new FatalErrorException(); }
|
|
76
|
+
|
|
77
|
+
this._stop();
|
|
78
|
+
this._handle = undefined;
|
|
79
|
+
this._isRunning = false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public readonly [Symbol.toStringTag]: string = "GameLoop";
|
|
83
|
+
}
|
package/src/models/index.ts
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
export {
|
|
2
|
-
Aggregator,
|
|
3
|
-
AsyncAggregator,
|
|
4
2
|
AggregatedIterator,
|
|
5
3
|
AggregatedAsyncIterator,
|
|
6
4
|
ReducedIterator
|
|
7
5
|
|
|
8
6
|
} from "./aggregators/index.js";
|
|
9
7
|
|
|
8
|
+
export { CallableObject, Publisher, SmartFunction, SwitchableCallback } from "./callbacks/index.js";
|
|
10
9
|
export {
|
|
11
10
|
Exception,
|
|
12
11
|
FatalErrorException,
|
|
13
12
|
NotImplementedException,
|
|
13
|
+
FileException,
|
|
14
|
+
FileExistsException,
|
|
14
15
|
FileNotFoundException,
|
|
15
16
|
KeyException,
|
|
16
17
|
NetworkException,
|
|
17
18
|
PermissionException,
|
|
19
|
+
RangeException,
|
|
18
20
|
ReferenceException,
|
|
19
21
|
RuntimeException,
|
|
20
22
|
TimeoutException,
|
|
@@ -23,11 +25,12 @@ export {
|
|
|
23
25
|
|
|
24
26
|
} from "./exceptions/index.js";
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
import GameLoop from "./game-loop.js";
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
export { SmartIterator, SmartAsyncIterator } from "./iterators/index.js";
|
|
31
|
+
export { JSONStorage } from "./json/index.js";
|
|
32
|
+
export { DeferredPromise, LongRunningTask, SmartPromise, Thenable, TimedPromise } from "./promises/index.js";
|
|
30
33
|
|
|
31
|
-
export {
|
|
34
|
+
export { Clock, Countdown } from "./timers/index.js";
|
|
32
35
|
|
|
33
|
-
export {
|
|
36
|
+
export { GameLoop };
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import AggregatedAsyncIterator from "../aggregators/aggregated-async-iterator.js";
|
|
2
|
+
import { ValueException } from "../exceptions/index.js";
|
|
3
|
+
|
|
1
4
|
import type {
|
|
2
|
-
AsyncGeneratorFunction,
|
|
3
5
|
GeneratorFunction,
|
|
6
|
+
AsyncGeneratorFunction,
|
|
7
|
+
MaybeAsyncGeneratorFunction,
|
|
4
8
|
MaybeAsyncIteratee,
|
|
5
9
|
MaybeAsyncReducer,
|
|
6
|
-
|
|
10
|
+
MaybeAsyncIterable,
|
|
11
|
+
MaybeAsyncIteratorLike,
|
|
7
12
|
MaybeAsyncTypeGuardIteratee
|
|
8
13
|
|
|
9
14
|
} from "./types.js";
|
|
@@ -21,8 +26,8 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
|
|
|
21
26
|
public constructor(iterator: AsyncIterator<T, R, N>);
|
|
22
27
|
public constructor(generatorFn: GeneratorFunction<T, R, N>);
|
|
23
28
|
public constructor(generatorFn: AsyncGeneratorFunction<T, R, N>);
|
|
24
|
-
public constructor(argument:
|
|
25
|
-
public constructor(argument:
|
|
29
|
+
public constructor(argument: MaybeAsyncIteratorLike<T, R, N> | MaybeAsyncGeneratorFunction<T, R, N>);
|
|
30
|
+
public constructor(argument: MaybeAsyncIteratorLike<T, R, N> | MaybeAsyncGeneratorFunction<T, R, N>)
|
|
26
31
|
{
|
|
27
32
|
if (argument instanceof Function)
|
|
28
33
|
{
|
|
@@ -92,13 +97,12 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
|
|
|
92
97
|
{
|
|
93
98
|
let index = 0;
|
|
94
99
|
|
|
95
|
-
// eslint-disable-next-line no-constant-condition
|
|
96
100
|
while (true)
|
|
97
101
|
{
|
|
98
102
|
const result = await this._iterator.next();
|
|
99
103
|
|
|
100
104
|
if (result.done) { return true; }
|
|
101
|
-
if (!(predicate(result.value, index))) { return false; }
|
|
105
|
+
if (!(await predicate(result.value, index))) { return false; }
|
|
102
106
|
|
|
103
107
|
index += 1;
|
|
104
108
|
}
|
|
@@ -107,13 +111,12 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
|
|
|
107
111
|
{
|
|
108
112
|
let index = 0;
|
|
109
113
|
|
|
110
|
-
// eslint-disable-next-line no-constant-condition
|
|
111
114
|
while (true)
|
|
112
115
|
{
|
|
113
116
|
const result = await this._iterator.next();
|
|
114
117
|
|
|
115
118
|
if (result.done) { return false; }
|
|
116
|
-
if (predicate(result.value, index)) { return true; }
|
|
119
|
+
if (await predicate(result.value, index)) { return true; }
|
|
117
120
|
|
|
118
121
|
index += 1;
|
|
119
122
|
}
|
|
@@ -134,7 +137,7 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
|
|
|
134
137
|
const result = await iterator.next();
|
|
135
138
|
|
|
136
139
|
if (result.done) { return result.value; }
|
|
137
|
-
if (predicate(result.value, index)) { yield result.value; }
|
|
140
|
+
if (await predicate(result.value, index)) { yield result.value; }
|
|
138
141
|
|
|
139
142
|
index += 1;
|
|
140
143
|
}
|
|
@@ -153,7 +156,7 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
|
|
|
153
156
|
const result = await iterator.next();
|
|
154
157
|
if (result.done) { return result.value; }
|
|
155
158
|
|
|
156
|
-
yield iteratee(result.value, index);
|
|
159
|
+
yield await iteratee(result.value, index);
|
|
157
160
|
|
|
158
161
|
index += 1;
|
|
159
162
|
}
|
|
@@ -168,13 +171,12 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
|
|
|
168
171
|
if (accumulator === undefined)
|
|
169
172
|
{
|
|
170
173
|
const result = await this._iterator.next();
|
|
171
|
-
if (result.done) { throw new
|
|
174
|
+
if (result.done) { throw new ValueException("Cannot reduce an empty iterator without an initial value."); }
|
|
172
175
|
|
|
173
176
|
accumulator = (result.value as unknown) as A;
|
|
174
177
|
index += 1;
|
|
175
178
|
}
|
|
176
179
|
|
|
177
|
-
// eslint-disable-next-line no-constant-condition
|
|
178
180
|
while (true)
|
|
179
181
|
{
|
|
180
182
|
const result = await this._iterator.next();
|
|
@@ -186,6 +188,93 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
|
|
|
186
188
|
}
|
|
187
189
|
}
|
|
188
190
|
|
|
191
|
+
public flatMap<V>(iteratee: MaybeAsyncIteratee<T, MaybeAsyncIterable<V>>): SmartAsyncIterator<V, R>
|
|
192
|
+
{
|
|
193
|
+
const iterator = this._iterator;
|
|
194
|
+
|
|
195
|
+
return new SmartAsyncIterator<V, R>(async function* ()
|
|
196
|
+
{
|
|
197
|
+
let index = 0;
|
|
198
|
+
|
|
199
|
+
while (true)
|
|
200
|
+
{
|
|
201
|
+
const result = await iterator.next();
|
|
202
|
+
if (result.done) { return result.value; }
|
|
203
|
+
|
|
204
|
+
const elements = await iteratee(result.value, index);
|
|
205
|
+
|
|
206
|
+
for await (const element of elements)
|
|
207
|
+
{
|
|
208
|
+
yield element;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
index += 1;
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
public drop(count: number): SmartAsyncIterator<T, R | undefined>
|
|
217
|
+
{
|
|
218
|
+
const iterator = this._iterator;
|
|
219
|
+
|
|
220
|
+
return new SmartAsyncIterator<T, R | undefined>(async function* ()
|
|
221
|
+
{
|
|
222
|
+
let index = 0;
|
|
223
|
+
|
|
224
|
+
while (index < count)
|
|
225
|
+
{
|
|
226
|
+
const result = await iterator.next();
|
|
227
|
+
if (result.done) { return; }
|
|
228
|
+
|
|
229
|
+
index += 1;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
while (true)
|
|
233
|
+
{
|
|
234
|
+
const result = await iterator.next();
|
|
235
|
+
if (result.done) { return result.value; }
|
|
236
|
+
|
|
237
|
+
yield result.value;
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
public take(limit: number): SmartAsyncIterator<T, R | undefined>
|
|
242
|
+
{
|
|
243
|
+
const iterator = this._iterator;
|
|
244
|
+
|
|
245
|
+
return new SmartAsyncIterator<T, R | undefined>(async function* ()
|
|
246
|
+
{
|
|
247
|
+
let index = 0;
|
|
248
|
+
|
|
249
|
+
while (index < limit)
|
|
250
|
+
{
|
|
251
|
+
const result = await iterator.next();
|
|
252
|
+
if (result.done) { return result.value; }
|
|
253
|
+
|
|
254
|
+
yield result.value;
|
|
255
|
+
|
|
256
|
+
index += 1;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return;
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
public async find(predicate: MaybeAsyncIteratee<T, boolean>): Promise<T | undefined>
|
|
264
|
+
{
|
|
265
|
+
let index = 0;
|
|
266
|
+
|
|
267
|
+
while (true)
|
|
268
|
+
{
|
|
269
|
+
const result = await this._iterator.next();
|
|
270
|
+
|
|
271
|
+
if (result.done) { return; }
|
|
272
|
+
if (await predicate(result.value, index)) { return result.value; }
|
|
273
|
+
|
|
274
|
+
index += 1;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
189
278
|
public enumerate(): SmartAsyncIterator<[number, T], R>
|
|
190
279
|
{
|
|
191
280
|
return this.map((value, index) => [index, value]);
|
|
@@ -216,7 +305,6 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
|
|
|
216
305
|
{
|
|
217
306
|
let index = 0;
|
|
218
307
|
|
|
219
|
-
// eslint-disable-next-line no-constant-condition
|
|
220
308
|
while (true)
|
|
221
309
|
{
|
|
222
310
|
const result = await this._iterator.next();
|
|
@@ -229,7 +317,6 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
|
|
|
229
317
|
{
|
|
230
318
|
let index = 0;
|
|
231
319
|
|
|
232
|
-
// eslint-disable-next-line no-constant-condition
|
|
233
320
|
while (true)
|
|
234
321
|
{
|
|
235
322
|
const result = await this._iterator.next();
|
|
@@ -246,21 +333,22 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
|
|
|
246
333
|
return this._iterator.next(...values);
|
|
247
334
|
}
|
|
248
335
|
|
|
249
|
-
public
|
|
336
|
+
public groupBy<K extends PropertyKey>(iteratee: MaybeAsyncIteratee<T, K>): AggregatedAsyncIterator<K, T>
|
|
250
337
|
{
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
// eslint-disable-next-line no-constant-condition
|
|
254
|
-
while (true)
|
|
338
|
+
return new AggregatedAsyncIterator(this.map(async (element, index) =>
|
|
255
339
|
{
|
|
256
|
-
const
|
|
257
|
-
if (result.done) { return elements; }
|
|
340
|
+
const key = await iteratee(element, index);
|
|
258
341
|
|
|
259
|
-
|
|
260
|
-
}
|
|
342
|
+
return [key, element] as [K, T];
|
|
343
|
+
}));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
public toArray(): Promise<T[]>
|
|
347
|
+
{
|
|
348
|
+
return Array.fromAsync(this as AsyncIterable<T>);
|
|
261
349
|
}
|
|
262
350
|
|
|
263
|
-
public
|
|
351
|
+
public readonly [Symbol.toStringTag]: string = "SmartAsyncIterator";
|
|
264
352
|
|
|
265
353
|
public [Symbol.asyncIterator](): SmartAsyncIterator<T, R, N> { return this; }
|
|
266
354
|
}
|