@byloth/core 2.0.0-rc.8 → 2.0.0
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 +3372 -609
- 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 +13 -10
- package/src/core/types.ts +41 -0
- package/src/helpers.ts +11 -2
- package/src/index.ts +12 -9
- package/src/models/aggregators/aggregated-async-iterator.ts +765 -21
- package/src/models/aggregators/aggregated-iterator.ts +698 -22
- package/src/models/aggregators/reduced-iterator.ts +699 -10
- package/src/models/aggregators/types.ts +153 -10
- package/src/models/callbacks/callable-object.ts +42 -6
- package/src/models/callbacks/index.ts +2 -2
- package/src/models/callbacks/publisher.ts +140 -5
- package/src/models/callbacks/switchable-callback.ts +143 -5
- package/src/models/callbacks/types.ts +16 -0
- package/src/models/exceptions/core.ts +112 -3
- package/src/models/exceptions/index.ts +340 -13
- package/src/models/index.ts +4 -8
- package/src/models/iterators/smart-async-iterator.ts +687 -22
- package/src/models/iterators/smart-iterator.ts +631 -21
- package/src/models/iterators/types.ts +268 -9
- package/src/models/json/json-storage.ts +388 -110
- package/src/models/json/types.ts +10 -1
- package/src/models/promises/deferred-promise.ts +75 -5
- package/src/models/promises/index.ts +1 -3
- package/src/models/promises/smart-promise.ts +232 -4
- package/src/models/promises/timed-promise.ts +38 -1
- package/src/models/promises/types.ts +84 -2
- package/src/models/timers/clock.ts +91 -19
- package/src/models/timers/countdown.ts +152 -22
- package/src/models/timers/game-loop.ts +243 -0
- package/src/models/timers/index.ts +2 -1
- package/src/models/types.ts +6 -5
- package/src/utils/async.ts +43 -0
- package/src/utils/curve.ts +75 -0
- package/src/utils/date.ts +204 -10
- package/src/utils/dom.ts +16 -2
- package/src/utils/index.ts +3 -2
- package/src/utils/iterator.ts +200 -17
- package/src/utils/math.ts +55 -3
- package/src/utils/random.ts +109 -2
- package/src/utils/string.ts +11 -0
- package/src/models/game-loop.ts +0 -83
- package/src/models/promises/long-running-task.ts +0 -294
- package/src/models/promises/thenable.ts +0 -97
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
import { yieldToEventLoop } from "../../utils/async.js";
|
|
2
|
-
|
|
3
|
-
import Publisher from "../callbacks/publisher.js";
|
|
4
|
-
import { RuntimeException } from "../exceptions/index.js";
|
|
5
|
-
|
|
6
|
-
import type { MaybeAsyncGeneratorFunction } from "../iterators/types.js";
|
|
7
|
-
import type { FulfilledHandler, PromiseExecutor, RejectedHandler } from "./types.js";
|
|
8
|
-
|
|
9
|
-
export interface LongRunningTaskOptions
|
|
10
|
-
{
|
|
11
|
-
ignoreErrors?: boolean;
|
|
12
|
-
stepIncrement?: number;
|
|
13
|
-
totalSteps?: number | null;
|
|
14
|
-
trackProgress?: boolean;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export default class LongRunningTask<T = void> implements Promise<T>
|
|
18
|
-
{
|
|
19
|
-
private static get _DefaultOptions(): Required<LongRunningTaskOptions>
|
|
20
|
-
{
|
|
21
|
-
return {
|
|
22
|
-
ignoreErrors: false,
|
|
23
|
-
stepIncrement: 1,
|
|
24
|
-
totalSteps: null,
|
|
25
|
-
trackProgress: false
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
protected _startTime: number;
|
|
30
|
-
protected _estimatedTime: number;
|
|
31
|
-
protected _endTime?: number;
|
|
32
|
-
|
|
33
|
-
protected _currentStep: number;
|
|
34
|
-
protected _percentage: number;
|
|
35
|
-
|
|
36
|
-
protected _isRunning: boolean;
|
|
37
|
-
protected _hasCompleted: boolean;
|
|
38
|
-
protected _hasFailed: boolean;
|
|
39
|
-
|
|
40
|
-
protected _promise: Promise<T>;
|
|
41
|
-
protected _publisher?: Publisher;
|
|
42
|
-
|
|
43
|
-
public constructor(executor: MaybeAsyncGeneratorFunction<undefined, T>, options?: LongRunningTaskOptions);
|
|
44
|
-
public constructor(executor: MaybeAsyncGeneratorFunction<number, T>, options?: LongRunningTaskOptions);
|
|
45
|
-
public constructor(executor: MaybeAsyncGeneratorFunction<number | undefined, T>, options?: LongRunningTaskOptions)
|
|
46
|
-
{
|
|
47
|
-
this._startTime = 0;
|
|
48
|
-
this._estimatedTime = 0;
|
|
49
|
-
|
|
50
|
-
this._currentStep = 0;
|
|
51
|
-
this._percentage = 0;
|
|
52
|
-
|
|
53
|
-
this._isRunning = true;
|
|
54
|
-
this._hasCompleted = false;
|
|
55
|
-
this._hasFailed = false;
|
|
56
|
-
|
|
57
|
-
const _onFulfilled = (result: T): T =>
|
|
58
|
-
{
|
|
59
|
-
this._estimatedTime = 0;
|
|
60
|
-
this._endTime = Date.now();
|
|
61
|
-
|
|
62
|
-
this._percentage = 100;
|
|
63
|
-
|
|
64
|
-
this._isRunning = false;
|
|
65
|
-
this._hasCompleted = true;
|
|
66
|
-
|
|
67
|
-
return result;
|
|
68
|
-
};
|
|
69
|
-
const _onRejected = (reason: unknown): never =>
|
|
70
|
-
{
|
|
71
|
-
this._endTime = Date.now();
|
|
72
|
-
|
|
73
|
-
this._isRunning = false;
|
|
74
|
-
this._hasFailed = true;
|
|
75
|
-
|
|
76
|
-
throw reason;
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
let _executor: PromiseExecutor<T>;
|
|
80
|
-
|
|
81
|
-
options = { ...LongRunningTask._DefaultOptions, ...options };
|
|
82
|
-
if ((options.trackProgress))
|
|
83
|
-
{
|
|
84
|
-
let _trackProgress: (steps: number | undefined) => void;
|
|
85
|
-
|
|
86
|
-
this._publisher = new Publisher();
|
|
87
|
-
|
|
88
|
-
if (options.totalSteps)
|
|
89
|
-
{
|
|
90
|
-
if (options.stepIncrement)
|
|
91
|
-
{
|
|
92
|
-
_trackProgress = (steps: number | undefined) =>
|
|
93
|
-
{
|
|
94
|
-
if (steps) { this._currentStep += steps; }
|
|
95
|
-
else { this._currentStep += options.stepIncrement!; }
|
|
96
|
-
|
|
97
|
-
this._percentage = (this._currentStep / options.totalSteps!) * 100;
|
|
98
|
-
|
|
99
|
-
const elapsedTime = Date.now() - this._startTime;
|
|
100
|
-
const remainingSteps = options.totalSteps! - this._currentStep;
|
|
101
|
-
this._estimatedTime = (elapsedTime / this._currentStep) * remainingSteps;
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
else
|
|
105
|
-
{
|
|
106
|
-
_trackProgress = (steps: number | undefined) =>
|
|
107
|
-
{
|
|
108
|
-
if (steps)
|
|
109
|
-
{
|
|
110
|
-
this._currentStep += steps;
|
|
111
|
-
this._percentage = (this._currentStep / options.totalSteps!) * 100;
|
|
112
|
-
|
|
113
|
-
const elapsedTime = Date.now() - this._startTime;
|
|
114
|
-
const remainingSteps = options.totalSteps! - this._currentStep;
|
|
115
|
-
this._estimatedTime = (elapsedTime / this._currentStep) * remainingSteps;
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
else if (options.stepIncrement)
|
|
121
|
-
{
|
|
122
|
-
_trackProgress = (steps: number | undefined) =>
|
|
123
|
-
{
|
|
124
|
-
if (steps) { this._currentStep += steps; }
|
|
125
|
-
else { this._currentStep += options.stepIncrement!; }
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
else
|
|
129
|
-
{
|
|
130
|
-
_trackProgress = (steps: number | undefined) =>
|
|
131
|
-
{
|
|
132
|
-
if (steps) { this._currentStep += steps; }
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (options.ignoreErrors)
|
|
137
|
-
{
|
|
138
|
-
_executor = async (resolve) =>
|
|
139
|
-
{
|
|
140
|
-
const generator = executor();
|
|
141
|
-
this._startTime = Date.now();
|
|
142
|
-
|
|
143
|
-
while (true)
|
|
144
|
-
{
|
|
145
|
-
try
|
|
146
|
-
{
|
|
147
|
-
const { done, value } = await generator.next();
|
|
148
|
-
|
|
149
|
-
if (done) { return resolve(value); }
|
|
150
|
-
else { _trackProgress(value); }
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// eslint-disable-next-line no-console
|
|
154
|
-
catch (error) { console.error(error); }
|
|
155
|
-
|
|
156
|
-
this._publisher!.publish("progress");
|
|
157
|
-
|
|
158
|
-
await yieldToEventLoop();
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
else
|
|
163
|
-
{
|
|
164
|
-
_executor = async (resolve, reject) =>
|
|
165
|
-
{
|
|
166
|
-
try
|
|
167
|
-
{
|
|
168
|
-
const generator = executor();
|
|
169
|
-
this._startTime = Date.now();
|
|
170
|
-
|
|
171
|
-
while (true)
|
|
172
|
-
{
|
|
173
|
-
const { done, value } = await generator.next();
|
|
174
|
-
if (done) { return resolve(value); }
|
|
175
|
-
else { _trackProgress(value); }
|
|
176
|
-
|
|
177
|
-
this._publisher!.publish("progress");
|
|
178
|
-
|
|
179
|
-
await yieldToEventLoop();
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
catch (error) { reject(error); }
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
else if (options.ignoreErrors)
|
|
187
|
-
{
|
|
188
|
-
_executor = async (resolve) =>
|
|
189
|
-
{
|
|
190
|
-
const generator = executor();
|
|
191
|
-
this._startTime = Date.now();
|
|
192
|
-
|
|
193
|
-
while (true)
|
|
194
|
-
{
|
|
195
|
-
try
|
|
196
|
-
{
|
|
197
|
-
const { done, value } = await generator.next();
|
|
198
|
-
if (done) { return resolve(value); }
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// eslint-disable-next-line no-console
|
|
202
|
-
catch (error) { console.error(error); }
|
|
203
|
-
|
|
204
|
-
await yieldToEventLoop();
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
else
|
|
209
|
-
{
|
|
210
|
-
_executor = async (resolve, reject) =>
|
|
211
|
-
{
|
|
212
|
-
try
|
|
213
|
-
{
|
|
214
|
-
const generator = executor();
|
|
215
|
-
this._startTime = Date.now();
|
|
216
|
-
|
|
217
|
-
while (true)
|
|
218
|
-
{
|
|
219
|
-
const { done, value } = await generator.next();
|
|
220
|
-
if (done) { return resolve(value); }
|
|
221
|
-
|
|
222
|
-
await yieldToEventLoop();
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
catch (error) { reject(error); }
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
this._promise = new Promise(_executor)
|
|
230
|
-
.then(_onFulfilled, _onRejected);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
public get startTime(): number { return this._startTime; }
|
|
234
|
-
public get elapsedTime(): number
|
|
235
|
-
{
|
|
236
|
-
if (this._isRunning) { return Date.now() - this._startTime; }
|
|
237
|
-
|
|
238
|
-
return this._endTime! - this._startTime;
|
|
239
|
-
}
|
|
240
|
-
public get estimatedTime(): number { return this._estimatedTime; }
|
|
241
|
-
public get endTime(): number
|
|
242
|
-
{
|
|
243
|
-
if (this._isRunning)
|
|
244
|
-
{
|
|
245
|
-
throw new RuntimeException("The task is still running and has no end time yet.");
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return this._endTime!;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
public get currentStep(): number { return this._currentStep; }
|
|
252
|
-
public get percentage(): number { return this._percentage; }
|
|
253
|
-
|
|
254
|
-
public get isRunning(): boolean { return this._isRunning; }
|
|
255
|
-
public get hasCompleted(): boolean { return this._hasCompleted; }
|
|
256
|
-
public get hasFailed(): boolean { return this._hasFailed; }
|
|
257
|
-
|
|
258
|
-
public then(onFulfilled?: null): Promise<T>;
|
|
259
|
-
public then<F = T>(onFulfilled: FulfilledHandler<T, F>, onRejected?: null): Promise<F>;
|
|
260
|
-
public then<F = T, R = never>(onFulfilled: FulfilledHandler<T, F>, onRejected: RejectedHandler<unknown, R>)
|
|
261
|
-
: Promise<F | R>;
|
|
262
|
-
public then<F = T, R = never>(
|
|
263
|
-
onFulfilled?: FulfilledHandler<T, F> | null,
|
|
264
|
-
onRejected?: RejectedHandler<unknown, R> | null): Promise<F | R>
|
|
265
|
-
{
|
|
266
|
-
return this._promise.then(onFulfilled, onRejected);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
public catch(onRejected?: null): Promise<T>;
|
|
270
|
-
public catch<R = never>(onRejected: RejectedHandler<unknown, R>): Promise<T | R>;
|
|
271
|
-
public catch<R = never>(onRejected?: RejectedHandler<unknown, R> | null): Promise<T | R>
|
|
272
|
-
{
|
|
273
|
-
return this._promise.catch(onRejected);
|
|
274
|
-
}
|
|
275
|
-
public finally(onFinally?: (() => void) | null): Promise<T>
|
|
276
|
-
{
|
|
277
|
-
return this._promise.finally(onFinally);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
public onProgress(callback: () => void): () => void
|
|
281
|
-
{
|
|
282
|
-
if (!(this._publisher))
|
|
283
|
-
{
|
|
284
|
-
throw new RuntimeException(
|
|
285
|
-
"You cannot subscribe to progress events without enabling progress tracking. " +
|
|
286
|
-
"Did you forget to set the `trackProgress` option to `true` when creating the task?"
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return this._publisher.subscribe("progress", callback);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
public readonly [Symbol.toStringTag]: string = "LongRunningTask";
|
|
294
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
export default class Thenable<T> implements Promise<T>
|
|
2
|
-
{
|
|
3
|
-
protected _onFulfilled: (result: T) => T;
|
|
4
|
-
protected _resolve(result: T): T
|
|
5
|
-
{
|
|
6
|
-
return this._onFulfilled(result);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
public constructor()
|
|
10
|
-
{
|
|
11
|
-
this._onFulfilled = (result: T) => result;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
public then(onFulfilled?: null): Thenable<T>;
|
|
15
|
-
public then<F = T>(onFulfilled: (result: T) => F, onRejected?: null): Thenable<F>;
|
|
16
|
-
public then<F = T, R = never>(onFulfilled: (result: T) => F, onRejected: (reason: unknown) => R)
|
|
17
|
-
: Thenable<F | R>;
|
|
18
|
-
public then<F = T, R = never>(onFulfilled?: ((result: T) => F) | null, onRejected?: ((reason: unknown) => R) | null)
|
|
19
|
-
: Thenable<F | R>
|
|
20
|
-
{
|
|
21
|
-
if (onRejected)
|
|
22
|
-
{
|
|
23
|
-
const _previousOnFulfilled = this._onFulfilled;
|
|
24
|
-
this._onFulfilled = (result: T) =>
|
|
25
|
-
{
|
|
26
|
-
try
|
|
27
|
-
{
|
|
28
|
-
result = _previousOnFulfilled(result);
|
|
29
|
-
|
|
30
|
-
return (onFulfilled!(result) as unknown) as T;
|
|
31
|
-
}
|
|
32
|
-
catch (error)
|
|
33
|
-
{
|
|
34
|
-
return (onRejected(error) as unknown) as T;
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
else if (onFulfilled)
|
|
39
|
-
{
|
|
40
|
-
const _previousOnFulfilled = this._onFulfilled;
|
|
41
|
-
this._onFulfilled = (result: T) =>
|
|
42
|
-
{
|
|
43
|
-
result = _previousOnFulfilled(result);
|
|
44
|
-
|
|
45
|
-
return (onFulfilled(result) as unknown) as T;
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return (this as unknown) as Thenable<F | R>;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
public catch(onRejected?: null): Thenable<T>;
|
|
53
|
-
public catch<R = never>(onRejected: (reason: unknown) => R): Thenable<T | R>;
|
|
54
|
-
public catch<R = never>(onRejected?: ((reason: unknown) => R) | null): Thenable<T | R>
|
|
55
|
-
{
|
|
56
|
-
if (onRejected)
|
|
57
|
-
{
|
|
58
|
-
const _previousOnFulfilled = this._onFulfilled;
|
|
59
|
-
this._onFulfilled = (result) =>
|
|
60
|
-
{
|
|
61
|
-
try
|
|
62
|
-
{
|
|
63
|
-
return _previousOnFulfilled(result);
|
|
64
|
-
}
|
|
65
|
-
catch (error)
|
|
66
|
-
{
|
|
67
|
-
return (onRejected(error) as unknown) as T;
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return this as Thenable<T | R>;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
public finally(onFinally?: (() => void) | null): Thenable<T>
|
|
76
|
-
{
|
|
77
|
-
if (onFinally)
|
|
78
|
-
{
|
|
79
|
-
const _previousOnFulfilled = this._onFulfilled;
|
|
80
|
-
this._onFulfilled = (result) =>
|
|
81
|
-
{
|
|
82
|
-
try
|
|
83
|
-
{
|
|
84
|
-
return _previousOnFulfilled(result);
|
|
85
|
-
}
|
|
86
|
-
finally
|
|
87
|
-
{
|
|
88
|
-
onFinally();
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return this;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
public readonly [Symbol.toStringTag]: string = "Thenable";
|
|
97
|
-
}
|