@byloth/core 2.0.0-rc.3 → 2.0.0-rc.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byloth/core",
3
- "version": "2.0.0-rc.3",
3
+ "version": "2.0.0-rc.5",
4
4
  "description": "An unopinionated collection of useful functions and classes that I use widely in all my projects. 🔧",
5
5
  "keywords": [
6
6
  "Core",
@@ -47,21 +47,18 @@
47
47
  },
48
48
  "types": "./src/index.ts",
49
49
  "devDependencies": {
50
- "@byloth/eslint-config-typescript": "^2.8.3",
51
- "@types/node": "^20.16.5",
52
- "@typescript-eslint/eslint-plugin": "^7.18.0",
53
- "@typescript-eslint/parser": "^7.18.0",
54
- "eslint": "^8.57.1",
50
+ "@byloth/eslint-config-typescript": "^3.0.1",
51
+ "@types/node": "^20.17.6",
55
52
  "husky": "^9.1.6",
56
- "typescript": "^5.6.2",
57
- "vite": "^5.4.7"
53
+ "typescript": "^5.6.3",
54
+ "vite": "^5.4.10"
58
55
  },
59
56
  "scripts": {
60
57
  "dev": "vite",
61
58
  "build": "vite build",
62
59
  "preview": "vite preview",
63
60
  "typecheck": "tsc",
64
- "lint": "eslint --ext .cjs,.js,.json,.ts --ignore-path .gitignore .",
61
+ "lint": "eslint .",
65
62
  "test": "vitest",
66
63
  "ci": "pnpm install --frozen-lockfile"
67
64
  }
package/src/helpers.ts CHANGED
@@ -1,3 +1,10 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+
3
+ // @ts-ignore
1
4
  export const isBrowser = ((typeof window !== "undefined") && (typeof window.document !== "undefined"));
5
+
6
+ // @ts-ignore
2
7
  export const isNode = ((typeof process !== "undefined") && (process.versions?.node));
8
+
9
+ // @ts-ignore
3
10
  export const isWebWorker = ((typeof self === "object") && (self.constructor?.name === "DedicatedWorkerGlobalScope"));
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export const VERSION = "2.0.0-rc.3";
1
+ export const VERSION = "2.0.0-rc.5";
2
2
 
3
3
  export type { Constructor, Interval, Timeout } from "./core/types.js";
4
4
 
@@ -29,6 +29,7 @@ export {
29
29
  SmartIterator,
30
30
  SmartAsyncIterator,
31
31
  SmartPromise,
32
+ Thenable,
32
33
  TimeoutException,
33
34
  TimedPromise,
34
35
  TypeException,
@@ -204,11 +204,11 @@ export default class AggregatedAsyncIterator<K extends PropertyKey, T>
204
204
  });
205
205
  }
206
206
 
207
- public async find(predicate: MaybeAsyncKeyedIteratee<K, T, boolean>): Promise<ReducedIterator<K, T | void>>;
207
+ public async find(predicate: MaybeAsyncKeyedIteratee<K, T, boolean>): Promise<ReducedIterator<K, T | undefined>>;
208
208
  public async find<S extends T>(predicate: MaybeAsyncKeyedTypeGuardIteratee<K, T, S>)
209
- : Promise<ReducedIterator<K, S | void>>;
209
+ : Promise<ReducedIterator<K, S | undefined>>;
210
210
 
211
- public async find(predicate: MaybeAsyncKeyedIteratee<K, T, boolean>): Promise<ReducedIterator<K, T | void>>
211
+ public async find(predicate: MaybeAsyncKeyedIteratee<K, T, boolean>): Promise<ReducedIterator<K, T | undefined>>
212
212
  {
213
213
  const values = new Map<K, [number, T | undefined]>();
214
214
 
@@ -347,5 +347,5 @@ export default class AggregatedAsyncIterator<K extends PropertyKey, T>
347
347
  return groups;
348
348
  }
349
349
 
350
- public get [Symbol.toStringTag]() { return "AggregatedAsyncIterator"; }
350
+ public readonly [Symbol.toStringTag]: string = "AggregatedAsyncIterator";
351
351
  }
@@ -192,9 +192,9 @@ export default class AggregatedIterator<K extends PropertyKey, T>
192
192
  });
193
193
  }
194
194
 
195
- public find(predicate: KeyedIteratee<K, T, boolean>): ReducedIterator<K, T | void>;
196
- public find<S extends T>(predicate: KeyedTypeGuardIteratee<K, T, S>): ReducedIterator<K, S | void>;
197
- public find(predicate: KeyedIteratee<K, T, boolean>): ReducedIterator<K, T | void>
195
+ public find(predicate: KeyedIteratee<K, T, boolean>): ReducedIterator<K, T | undefined>;
196
+ public find<S extends T>(predicate: KeyedTypeGuardIteratee<K, T, S>): ReducedIterator<K, S | undefined>;
197
+ public find(predicate: KeyedIteratee<K, T, boolean>): ReducedIterator<K, T | undefined>
198
198
  {
199
199
  const values = new Map<K, [number, T | undefined]>();
200
200
 
@@ -337,5 +337,5 @@ export default class AggregatedIterator<K extends PropertyKey, T>
337
337
  return groups;
338
338
  }
339
339
 
340
- public get [Symbol.toStringTag]() { return "AggregatedIterator"; }
340
+ public readonly [Symbol.toStringTag]: string = "AggregatedIterator";
341
341
  }
@@ -209,5 +209,5 @@ export default class ReducedIterator<K extends PropertyKey, T>
209
209
  return Object.fromEntries(this.items()) as Record<K, T>;
210
210
  }
211
211
 
212
- public get [Symbol.toStringTag]() { return "ReducedIterator"; }
212
+ public readonly [Symbol.toStringTag]: string = "ReducedIterator";
213
213
  }
@@ -39,7 +39,7 @@ export default class Exception extends Error
39
39
  }
40
40
  }
41
41
 
42
- public get [Symbol.toStringTag]() { return "Exception"; }
42
+ public readonly [Symbol.toStringTag]: string = "Exception";
43
43
  }
44
44
 
45
45
  export class FatalErrorException extends Exception
@@ -55,7 +55,7 @@ export class FatalErrorException extends Exception
55
55
  super(message, cause, name);
56
56
  }
57
57
 
58
- public get [Symbol.toStringTag]() { return "FatalErrorException"; }
58
+ public readonly [Symbol.toStringTag]: string = "FatalErrorException";
59
59
  }
60
60
  export class NotImplementedException extends FatalErrorException
61
61
  {
@@ -69,5 +69,5 @@ export class NotImplementedException extends FatalErrorException
69
69
  super(message, cause, name);
70
70
  }
71
71
 
72
- public get [Symbol.toStringTag]() { return "NotImplementedException"; }
72
+ public readonly [Symbol.toStringTag]: string = "NotImplementedException";
73
73
  }
@@ -7,7 +7,7 @@ export class FileException extends Exception
7
7
  super(message, cause, name);
8
8
  }
9
9
 
10
- public get [Symbol.toStringTag]() { return "FileException"; }
10
+ public readonly [Symbol.toStringTag]: string = "FileException";
11
11
  }
12
12
  export class FileExistsException extends FileException
13
13
  {
@@ -16,7 +16,7 @@ export class FileExistsException extends FileException
16
16
  super(message, cause, name);
17
17
  }
18
18
 
19
- public get [Symbol.toStringTag]() { return "FileExistsException"; }
19
+ public readonly [Symbol.toStringTag]: string = "FileExistsException";
20
20
  }
21
21
  export class FileNotFoundException extends FileException
22
22
  {
@@ -25,7 +25,7 @@ export class FileNotFoundException extends FileException
25
25
  super(message, cause, name);
26
26
  }
27
27
 
28
- public get [Symbol.toStringTag]() { return "FileNotFoundException"; }
28
+ public readonly [Symbol.toStringTag]: string = "FileNotFoundException";
29
29
  }
30
30
 
31
31
  export class KeyException extends Exception
@@ -35,7 +35,7 @@ export class KeyException extends Exception
35
35
  super(message, cause, name);
36
36
  }
37
37
 
38
- public get [Symbol.toStringTag]() { return "KeyException"; }
38
+ public readonly [Symbol.toStringTag]: string = "KeyException";
39
39
  }
40
40
  export class NetworkException extends Exception
41
41
  {
@@ -44,7 +44,7 @@ export class NetworkException extends Exception
44
44
  super(message, cause, name);
45
45
  }
46
46
 
47
- public get [Symbol.toStringTag]() { return "NetworkException"; }
47
+ public readonly [Symbol.toStringTag]: string = "NetworkException";
48
48
  }
49
49
  export class PermissionException extends Exception
50
50
  {
@@ -53,7 +53,7 @@ export class PermissionException extends Exception
53
53
  super(message, cause, name);
54
54
  }
55
55
 
56
- public get [Symbol.toStringTag]() { return "PermissionException"; }
56
+ public readonly [Symbol.toStringTag]: string = "PermissionException";
57
57
  }
58
58
  export class ReferenceException extends Exception
59
59
  {
@@ -62,7 +62,7 @@ export class ReferenceException extends Exception
62
62
  super(message, cause, name);
63
63
  }
64
64
 
65
- public get [Symbol.toStringTag]() { return "ReferenceException"; }
65
+ public readonly [Symbol.toStringTag]: string = "ReferenceException";
66
66
  }
67
67
 
68
68
  export class RuntimeException extends Exception
@@ -72,7 +72,7 @@ export class RuntimeException extends Exception
72
72
  super(message, cause, name);
73
73
  }
74
74
 
75
- public get [Symbol.toStringTag]() { return "RuntimeException"; }
75
+ public readonly [Symbol.toStringTag]: string = "RuntimeException";
76
76
  }
77
77
  export class EnvironmentException extends RuntimeException
78
78
  {
@@ -81,7 +81,7 @@ export class EnvironmentException extends RuntimeException
81
81
  super(message, cause, name);
82
82
  }
83
83
 
84
- public get [Symbol.toStringTag]() { return "EnvironmentException"; }
84
+ public readonly [Symbol.toStringTag]: string = "EnvironmentException";
85
85
  }
86
86
 
87
87
  export class TimeoutException extends Exception
@@ -91,7 +91,7 @@ export class TimeoutException extends Exception
91
91
  super(message, cause, name);
92
92
  }
93
93
 
94
- public get [Symbol.toStringTag]() { return "TimeoutException"; }
94
+ public readonly [Symbol.toStringTag]: string = "TimeoutException";
95
95
  }
96
96
  export class TypeException extends Exception
97
97
  {
@@ -100,7 +100,7 @@ export class TypeException extends Exception
100
100
  super(message, cause, name);
101
101
  }
102
102
 
103
- public get [Symbol.toStringTag]() { return "TypeException"; }
103
+ public readonly [Symbol.toStringTag]: string = "TypeException";
104
104
  }
105
105
 
106
106
  export class ValueException extends Exception
@@ -110,7 +110,7 @@ export class ValueException extends Exception
110
110
  super(message, cause, name);
111
111
  }
112
112
 
113
- public get [Symbol.toStringTag]() { return "ValueException"; }
113
+ public readonly [Symbol.toStringTag]: string = "ValueException";
114
114
  }
115
115
  export class RangeException extends ValueException
116
116
  {
@@ -119,7 +119,7 @@ export class RangeException extends ValueException
119
119
  super(message, cause, name);
120
120
  }
121
121
 
122
- public get [Symbol.toStringTag]() { return "RangeException"; }
122
+ public readonly [Symbol.toStringTag]: string = "RangeException";
123
123
  }
124
124
 
125
125
  export { Exception };
@@ -1,11 +1,11 @@
1
+ import type { Interval } from "../core/types.js";
1
2
  import { isBrowser } from "../helpers.js";
2
- import { TimeUnit } from "../utils/date.js";
3
3
 
4
4
  import { FatalErrorException, RuntimeException } from "./exceptions/index.js";
5
5
 
6
6
  export default class GameLoop
7
7
  {
8
- protected _handle?: number;
8
+ protected _handle?: number | Interval;
9
9
 
10
10
  protected _startTime: number;
11
11
  public get startTime(): number
@@ -27,7 +27,7 @@ export default class GameLoop
27
27
  protected _start: () => void;
28
28
  protected _stop: () => void;
29
29
 
30
- public constructor(callback: FrameRequestCallback, fpsIfNotBrowser = 30)
30
+ public constructor(callback: FrameRequestCallback, msIfNotBrowser = 40)
31
31
  {
32
32
  this._startTime = 0;
33
33
  this._isRunning = false;
@@ -41,24 +41,22 @@ export default class GameLoop
41
41
  this._handle = window.requestAnimationFrame(this._start);
42
42
  };
43
43
 
44
- this._stop = () => window.cancelAnimationFrame(this._handle!);
44
+ this._stop = () => window.cancelAnimationFrame(this._handle as number);
45
45
  }
46
46
  else
47
47
  {
48
48
  // eslint-disable-next-line no-console
49
49
  console.warn(
50
50
  "Not a browser environment detected. " +
51
- `Using setInterval@${fpsIfNotBrowser}fps instead of requestAnimationFrame...`
51
+ `Using setInterval@${msIfNotBrowser}ms instead of requestAnimationFrame...`
52
52
  );
53
53
 
54
54
  this._start = () =>
55
55
  {
56
- const delay = (TimeUnit.Second / fpsIfNotBrowser);
57
-
58
- this._handle = (setInterval(() => callback(this.elapsedTime), delay) as unknown) as number;
56
+ this._handle = setInterval(() => callback(this.elapsedTime), msIfNotBrowser);
59
57
  };
60
58
 
61
- this._stop = () => clearInterval(this._handle!);
59
+ this._stop = () => clearInterval(this._handle as Interval);
62
60
  }
63
61
  }
64
62
 
@@ -80,4 +78,6 @@ export default class GameLoop
80
78
  this._handle = undefined;
81
79
  this._isRunning = false;
82
80
  }
81
+
82
+ public readonly [Symbol.toStringTag]: string = "GameLoop";
83
83
  }
@@ -28,7 +28,7 @@ import GameLoop from "./game-loop.js";
28
28
 
29
29
  export { SmartIterator, SmartAsyncIterator } from "./iterators/index.js";
30
30
  export { JSONStorage } from "./json/index.js";
31
- export { DeferredPromise, SmartPromise, TimedPromise } from "./promises/index.js";
31
+ export { DeferredPromise, SmartPromise, Thenable, TimedPromise } from "./promises/index.js";
32
32
 
33
33
  import Publisher from "./publisher.js";
34
34
 
@@ -97,7 +97,6 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
97
97
  {
98
98
  let index = 0;
99
99
 
100
- // eslint-disable-next-line no-constant-condition
101
100
  while (true)
102
101
  {
103
102
  const result = await this._iterator.next();
@@ -112,7 +111,6 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
112
111
  {
113
112
  let index = 0;
114
113
 
115
- // eslint-disable-next-line no-constant-condition
116
114
  while (true)
117
115
  {
118
116
  const result = await this._iterator.next();
@@ -179,7 +177,6 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
179
177
  index += 1;
180
178
  }
181
179
 
182
- // eslint-disable-next-line no-constant-condition
183
180
  while (true)
184
181
  {
185
182
  const result = await this._iterator.next();
@@ -216,11 +213,11 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
216
213
  });
217
214
  }
218
215
 
219
- public drop(count: number): SmartAsyncIterator<T, R | void>
216
+ public drop(count: number): SmartAsyncIterator<T, R | undefined>
220
217
  {
221
218
  const iterator = this._iterator;
222
219
 
223
- return new SmartAsyncIterator<T, R | void>(async function* ()
220
+ return new SmartAsyncIterator<T, R | undefined>(async function* ()
224
221
  {
225
222
  let index = 0;
226
223
 
@@ -241,11 +238,11 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
241
238
  }
242
239
  });
243
240
  }
244
- public take(limit: number): SmartAsyncIterator<T, R | void>
241
+ public take(limit: number): SmartAsyncIterator<T, R | undefined>
245
242
  {
246
243
  const iterator = this._iterator;
247
244
 
248
- return new SmartAsyncIterator<T, R | void>(async function* ()
245
+ return new SmartAsyncIterator<T, R | undefined>(async function* ()
249
246
  {
250
247
  let index = 0;
251
248
 
@@ -263,11 +260,10 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
263
260
  });
264
261
  }
265
262
 
266
- public async find(predicate: MaybeAsyncIteratee<T, boolean>): Promise<T | void>
263
+ public async find(predicate: MaybeAsyncIteratee<T, boolean>): Promise<T | undefined>
267
264
  {
268
265
  let index = 0;
269
266
 
270
- // eslint-disable-next-line no-constant-condition
271
267
  while (true)
272
268
  {
273
269
  const result = await this._iterator.next();
@@ -309,7 +305,6 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
309
305
  {
310
306
  let index = 0;
311
307
 
312
- // eslint-disable-next-line no-constant-condition
313
308
  while (true)
314
309
  {
315
310
  const result = await this._iterator.next();
@@ -322,7 +317,6 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
322
317
  {
323
318
  let index = 0;
324
319
 
325
- // eslint-disable-next-line no-constant-condition
326
320
  while (true)
327
321
  {
328
322
  const result = await this._iterator.next();
@@ -354,7 +348,7 @@ export default class SmartAsyncIterator<T, R = void, N = undefined> implements A
354
348
  return Array.fromAsync(this as AsyncIterable<T>);
355
349
  }
356
350
 
357
- public get [Symbol.toStringTag]() { return "SmartAsyncIterator"; }
351
+ public readonly [Symbol.toStringTag]: string = "SmartAsyncIterator";
358
352
 
359
353
  public [Symbol.asyncIterator](): SmartAsyncIterator<T, R, N> { return this; }
360
354
  }
@@ -37,7 +37,6 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
37
37
  {
38
38
  let index = 0;
39
39
 
40
- // eslint-disable-next-line no-constant-condition
41
40
  while (true)
42
41
  {
43
42
  const result = this._iterator.next();
@@ -52,7 +51,6 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
52
51
  {
53
52
  let index = 0;
54
53
 
55
- // eslint-disable-next-line no-constant-condition
56
54
  while (true)
57
55
  {
58
56
  const result = this._iterator.next();
@@ -119,7 +117,6 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
119
117
  index += 1;
120
118
  }
121
119
 
122
- // eslint-disable-next-line no-constant-condition
123
120
  while (true)
124
121
  {
125
122
  const result = this._iterator.next();
@@ -155,11 +152,11 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
155
152
  });
156
153
  }
157
154
 
158
- public drop(count: number): SmartIterator<T, R | void>
155
+ public drop(count: number): SmartIterator<T, R | undefined>
159
156
  {
160
157
  const iterator = this._iterator;
161
158
 
162
- return new SmartIterator<T, R | void>(function* ()
159
+ return new SmartIterator<T, R | undefined>(function* ()
163
160
  {
164
161
  let index = 0;
165
162
  while (index < count)
@@ -179,11 +176,11 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
179
176
  }
180
177
  });
181
178
  }
182
- public take(limit: number): SmartIterator<T, R | void>
179
+ public take(limit: number): SmartIterator<T, R | undefined>
183
180
  {
184
181
  const iterator = this._iterator;
185
182
 
186
- return new SmartIterator<T, R | void>(function* ()
183
+ return new SmartIterator<T, R | undefined>(function* ()
187
184
  {
188
185
  let index = 0;
189
186
  while (index < limit)
@@ -200,13 +197,12 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
200
197
  });
201
198
  }
202
199
 
203
- public find(predicate: Iteratee<T, boolean>): T | void;
204
- public find<S extends T>(predicate: TypeGuardIteratee<T, S>): S | void;
205
- public find(predicate: Iteratee<T, boolean>): T | void
200
+ public find(predicate: Iteratee<T, boolean>): T | undefined;
201
+ public find<S extends T>(predicate: TypeGuardIteratee<T, S>): S | undefined;
202
+ public find(predicate: Iteratee<T, boolean>): T | undefined
206
203
  {
207
204
  let index = 0;
208
205
 
209
- // eslint-disable-next-line no-constant-condition
210
206
  while (true)
211
207
  {
212
208
  const result = this._iterator.next();
@@ -248,7 +244,6 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
248
244
  {
249
245
  let index = 0;
250
246
 
251
- // eslint-disable-next-line no-constant-condition
252
247
  while (true)
253
248
  {
254
249
  const result = this._iterator.next();
@@ -262,7 +257,6 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
262
257
  {
263
258
  let index = 0;
264
259
 
265
- // eslint-disable-next-line no-constant-condition
266
260
  while (true)
267
261
  {
268
262
  const result = this._iterator.next();
@@ -294,7 +288,7 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
294
288
  return Array.from(this as Iterable<T>);
295
289
  }
296
290
 
297
- public get [Symbol.toStringTag]() { return "SmartIterator"; }
291
+ public readonly [Symbol.toStringTag]: string = "SmartIterator";
298
292
 
299
293
  public [Symbol.iterator](): SmartIterator<T, R, N> { return this; }
300
294
  }
@@ -1,4 +1,3 @@
1
- /* eslint-disable max-len */
2
1
 
3
2
  import type { MaybePromise } from "../promises/types.js";
4
3
 
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-trailing-spaces */
2
1
 
3
2
  import { isBrowser } from "../../helpers.js";
4
3
  import { EnvironmentException } from "../exceptions/index.js";
@@ -45,7 +44,7 @@ export default class JSONStorage
45
44
  {
46
45
  return JSON.parse(propertyValue);
47
46
  }
48
- catch (error)
47
+ catch
49
48
  {
50
49
  // eslint-disable-next-line no-console
51
50
  console.warn(
@@ -252,5 +251,5 @@ export default class JSONStorage
252
251
  this._persistent.removeItem(propertyName);
253
252
  }
254
253
 
255
- public get [Symbol.toStringTag]() { return "JSONStorage"; }
254
+ public readonly [Symbol.toStringTag]: string = "JSONStorage";
256
255
  }
@@ -1,3 +1,7 @@
1
1
  export type JSONArray = JSONValue[];
2
- export type JSONObject = { [key: string]: JSONValue };
2
+
3
+ // @ts-expect-error - This is a circular reference to itself.
4
+ export type JSONObject = Record<string, JSONValue>;
5
+
6
+ // @ts-expect-error - This is a circular reference to itself.
3
7
  export type JSONValue = boolean | number | string | null | JSONObject | JSONArray;
@@ -37,5 +37,5 @@ export default class DeferredPromise<T = void, F = T, R = never> extends SmartPr
37
37
  return this;
38
38
  }
39
39
 
40
- public get [Symbol.toStringTag]() { return "DeferredPromise"; }
40
+ public readonly [Symbol.toStringTag]: string = "DeferredPromise";
41
41
  }
@@ -1,5 +1,6 @@
1
1
  import DeferredPromise from "./deferred-promise.js";
2
2
  import SmartPromise from "./smart-promise.js";
3
+ import Thenable from "./thenable.js";
3
4
  import TimedPromise from "./timed-promise.js";
4
5
 
5
- export { DeferredPromise, SmartPromise, TimedPromise };
6
+ export { DeferredPromise, SmartPromise, Thenable, TimedPromise };
@@ -64,5 +64,5 @@ export default class SmartPromise<T = void> implements Promise<T>
64
64
  return this._promise.finally(onFinally);
65
65
  }
66
66
 
67
- public get [Symbol.toStringTag]() { return "SmartPromise"; }
67
+ public readonly [Symbol.toStringTag]: string = "SmartPromise";
68
68
  }
@@ -0,0 +1,97 @@
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
+ }
@@ -27,5 +27,5 @@ export default class TimedPromise<T = void> extends SmartPromise<T>
27
27
  });
28
28
  }
29
29
 
30
- public get [Symbol.toStringTag]() { return "TimedPromise"; }
30
+ public readonly [Symbol.toStringTag]: string = "TimedPromise";
31
31
  }