@byloth/core 2.0.1 → 2.1.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/README.md +1 -0
- package/dist/core.cjs +6 -0
- package/dist/core.cjs.map +1 -0
- package/dist/{core.js → core.esm.js} +1098 -779
- package/dist/core.esm.js.map +1 -0
- package/dist/core.global.js +6 -0
- package/dist/core.global.js.map +1 -0
- package/dist/core.umd.cjs +3 -3
- package/dist/core.umd.cjs.map +1 -1
- package/package.json +15 -11
- package/src/core/types.ts +43 -10
- package/src/index.ts +9 -2
- package/src/models/aggregators/aggregated-async-iterator.ts +5 -0
- package/src/models/aggregators/aggregated-iterator.ts +5 -0
- package/src/models/aggregators/reduced-iterator.ts +18 -5
- package/src/models/aggregators/types.ts +35 -0
- package/src/models/callbacks/callable-object.ts +7 -0
- package/src/models/callbacks/publisher.ts +16 -12
- package/src/models/callbacks/switchable-callback.ts +9 -1
- package/src/models/callbacks/types.ts +35 -0
- package/src/models/collections/index.ts +4 -0
- package/src/models/collections/map-view.ts +206 -0
- package/src/models/collections/set-view.ts +204 -0
- package/src/models/collections/types.ts +25 -0
- package/src/models/exceptions/core.ts +10 -1
- package/src/models/exceptions/index.ts +40 -1
- package/src/models/index.ts +1 -0
- package/src/models/iterators/smart-async-iterator.ts +5 -0
- package/src/models/iterators/smart-iterator.ts +5 -0
- package/src/models/iterators/types.ts +79 -1
- package/src/models/json/json-storage.ts +4 -1
- package/src/models/json/types.ts +1 -1
- package/src/models/promises/deferred-promise.ts +5 -0
- package/src/models/promises/smart-promise.ts +5 -0
- package/src/models/promises/timed-promise.ts +5 -0
- package/src/models/promises/types.ts +30 -0
- package/src/models/timers/clock.ts +3 -0
- package/src/models/timers/countdown.ts +5 -0
- package/src/models/timers/game-loop.ts +3 -0
- package/src/models/types.ts +3 -8
- package/src/utils/async.ts +15 -0
- package/src/utils/curve.ts +1 -1
- package/src/utils/date.ts +36 -6
- package/src/utils/dom.ts +5 -0
- package/src/utils/iterator.ts +43 -3
- package/src/utils/math.ts +15 -0
- package/src/utils/random.ts +4 -0
- package/src/utils/string.ts +5 -0
- package/dist/core.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@byloth/core",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
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",
|
|
@@ -32,30 +32,33 @@
|
|
|
32
32
|
"src"
|
|
33
33
|
],
|
|
34
34
|
"main": "dist/core.umd.cjs",
|
|
35
|
-
"module": "dist/core.
|
|
35
|
+
"module": "dist/core.cjs",
|
|
36
|
+
"unpkg": "dist/core.global.js",
|
|
37
|
+
"jsdelivr": "dist/core.global.js",
|
|
36
38
|
"exports": {
|
|
37
39
|
".": {
|
|
38
40
|
"import": {
|
|
39
41
|
"types": "./src/index.ts",
|
|
40
|
-
"default": "./dist/core.js"
|
|
42
|
+
"default": "./dist/core.esm.js"
|
|
41
43
|
},
|
|
42
44
|
"require": {
|
|
43
45
|
"types": "./src/index.ts",
|
|
44
|
-
"default": "./dist/core.
|
|
46
|
+
"default": "./dist/core.cjs"
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
49
|
},
|
|
48
50
|
"types": "src/index.ts",
|
|
49
51
|
"devDependencies": {
|
|
50
52
|
"@byloth/eslint-config-typescript": "^3.1.0",
|
|
51
|
-
"@eslint/compat": "^1.2.
|
|
52
|
-
"@types/node": "^22.
|
|
53
|
-
"
|
|
53
|
+
"@eslint/compat": "^1.2.8",
|
|
54
|
+
"@types/node": "^22.15.2",
|
|
55
|
+
"@vitest/coverage-v8": "^3.1.2",
|
|
56
|
+
"eslint": "^9.25.1",
|
|
54
57
|
"husky": "^9.1.7",
|
|
55
|
-
"jsdom": "^26.
|
|
56
|
-
"typescript": "^5.8.
|
|
57
|
-
"vite": "^6.
|
|
58
|
-
"vitest": "^3.
|
|
58
|
+
"jsdom": "^26.1.0",
|
|
59
|
+
"typescript": "^5.8.3",
|
|
60
|
+
"vite": "^6.3.3",
|
|
61
|
+
"vitest": "^3.1.2"
|
|
59
62
|
},
|
|
60
63
|
"scripts": {
|
|
61
64
|
"dev": "vite",
|
|
@@ -64,6 +67,7 @@
|
|
|
64
67
|
"typecheck": "tsc",
|
|
65
68
|
"lint": "eslint .",
|
|
66
69
|
"test": "vitest run",
|
|
70
|
+
"test:coverage": "vitest run --coverage",
|
|
67
71
|
"ci": "pnpm install --frozen-lockfile"
|
|
68
72
|
}
|
|
69
73
|
}
|
package/src/core/types.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Is the counterpart of the native
|
|
2
|
+
* An utility type that allows to define a class constructor of a specific type.
|
|
3
|
+
* Is the counterpart of the native {@link InstanceType} utility type.
|
|
4
4
|
*
|
|
5
|
+
* ---
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
5
8
|
* ```ts
|
|
6
9
|
* function factory<T extends object>(Factory: Constructor<T>): T { [...] }
|
|
7
10
|
*
|
|
@@ -12,14 +15,17 @@
|
|
|
12
15
|
export type Constructor<T extends object, P extends unknown[] = any[]> = new (...args: P) => T;
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
|
-
* A type that represents the return value of
|
|
18
|
+
* A type that represents the return value of {@link setInterval} function,
|
|
16
19
|
* indipendently from the platform it's currently running on.
|
|
17
20
|
*
|
|
18
|
-
* For instance, in a browser environment, it's a
|
|
19
|
-
* In a Node.js environment, on the other hand, it's an object of type
|
|
21
|
+
* For instance, in a browser environment, it's a {@link Number} value representing the interval ID.
|
|
22
|
+
* In a Node.js environment, on the other hand, it's an object of type {@link NodeJS.Timeout}.
|
|
23
|
+
*
|
|
24
|
+
* This allows to seamlessly use the same code in both environments, without having to deal with the differences.
|
|
20
25
|
*
|
|
21
|
-
*
|
|
26
|
+
* ---
|
|
22
27
|
*
|
|
28
|
+
* @example
|
|
23
29
|
* ```ts
|
|
24
30
|
* const intervalId: Interval = setInterval(() => { [...] }, 1_000);
|
|
25
31
|
*
|
|
@@ -29,14 +35,17 @@ export type Constructor<T extends object, P extends unknown[] = any[]> = new (..
|
|
|
29
35
|
export type Interval = ReturnType<typeof setInterval>;
|
|
30
36
|
|
|
31
37
|
/**
|
|
32
|
-
* A type that represents the return value of
|
|
38
|
+
* A type that represents the return value of {@link setTimeout} function,
|
|
33
39
|
* indipendently from the platform it's currently running on.
|
|
34
40
|
*
|
|
35
|
-
* For instance, in a browser environment, it's a
|
|
36
|
-
* In a Node.js environment, on the other hand, it's an object of type
|
|
41
|
+
* For instance, in a browser environment, it's a {@link Number} value representing the timeout ID.
|
|
42
|
+
* In a Node.js environment, on the other hand, it's an object of type {@link NodeJS.Timeout}.
|
|
37
43
|
*
|
|
38
|
-
* This allows to seamlessly use the same code in both environments, without having to deal with the differences
|
|
44
|
+
* This allows to seamlessly use the same code in both environments, without having to deal with the differences.
|
|
39
45
|
*
|
|
46
|
+
* ---
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
40
49
|
* ```ts
|
|
41
50
|
* const timeoutId: Timeout = setTimeout(() => { [...] }, 1_000);
|
|
42
51
|
*
|
|
@@ -44,3 +53,27 @@ export type Interval = ReturnType<typeof setInterval>;
|
|
|
44
53
|
* ```
|
|
45
54
|
*/
|
|
46
55
|
export type Timeout = ReturnType<typeof setTimeout>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* An utility type that allows to extract the union of the values of a given type.
|
|
59
|
+
* It can be used to extract the values of all the properties of an object type.
|
|
60
|
+
*
|
|
61
|
+
* ---
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* class MyObject
|
|
66
|
+
* {
|
|
67
|
+
* protected secret = "Sssh! That's a secret!";
|
|
68
|
+
* public answer = 42;
|
|
69
|
+
* public greet() { console.log("Hello, world!"); }
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* type MyObjectProperties = ValueOf<MyObject>; // number | (() => void)
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* ---
|
|
76
|
+
*
|
|
77
|
+
* @template T The type to extract the values from.
|
|
78
|
+
*/
|
|
79
|
+
export type ValueOf<T> = T[keyof T];
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export const VERSION = "2.0
|
|
1
|
+
export const VERSION = "2.1.0";
|
|
2
2
|
|
|
3
|
-
export type { Constructor, Interval, Timeout } from "./core/types.js";
|
|
3
|
+
export type { Constructor, Interval, Timeout, ValueOf } from "./core/types.js";
|
|
4
4
|
|
|
5
5
|
export { isBrowser, isNode, isWorker } from "./helpers.js";
|
|
6
6
|
|
|
@@ -20,6 +20,7 @@ export {
|
|
|
20
20
|
GameLoop,
|
|
21
21
|
JSONStorage,
|
|
22
22
|
KeyException,
|
|
23
|
+
MapView,
|
|
23
24
|
NotImplementedException,
|
|
24
25
|
NetworkException,
|
|
25
26
|
PermissionException,
|
|
@@ -28,6 +29,7 @@ export {
|
|
|
28
29
|
ReducedIterator,
|
|
29
30
|
ReferenceException,
|
|
30
31
|
RuntimeException,
|
|
32
|
+
SetView,
|
|
31
33
|
SmartIterator,
|
|
32
34
|
SmartAsyncIterator,
|
|
33
35
|
SmartPromise,
|
|
@@ -47,6 +49,7 @@ export type {
|
|
|
47
49
|
AsyncKeyedReducer,
|
|
48
50
|
AsyncReducer,
|
|
49
51
|
Callback,
|
|
52
|
+
CallbackMap,
|
|
50
53
|
FulfilledHandler,
|
|
51
54
|
GeneratorFunction,
|
|
52
55
|
Iteratee,
|
|
@@ -57,6 +60,7 @@ export type {
|
|
|
57
60
|
KeyedIteratee,
|
|
58
61
|
KeyedReducer,
|
|
59
62
|
KeyedTypeGuardPredicate,
|
|
63
|
+
MapViewEventsMap,
|
|
60
64
|
MaybeAsyncKeyedIteratee,
|
|
61
65
|
MaybeAsyncKeyedReducer,
|
|
62
66
|
MaybeAsyncGeneratorFunction,
|
|
@@ -67,8 +71,11 @@ export type {
|
|
|
67
71
|
PromiseExecutor,
|
|
68
72
|
PromiseRejecter,
|
|
69
73
|
PromiseResolver,
|
|
74
|
+
ReadonlyMapView,
|
|
75
|
+
ReadonlySetView,
|
|
70
76
|
Reducer,
|
|
71
77
|
RejectedHandler,
|
|
78
|
+
SetViewEventsMap,
|
|
72
79
|
TypeGuardPredicate
|
|
73
80
|
|
|
74
81
|
} from "./models/types.js";
|
|
@@ -30,6 +30,9 @@ import type { MaybeAsyncKeyedIteratee, MaybeAsyncKeyedReducer } from "./types.js
|
|
|
30
30
|
* This is particularly useful when you need to group elements and
|
|
31
31
|
* then perform specific operations on the groups themselves.
|
|
32
32
|
*
|
|
33
|
+
* ---
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
33
36
|
* ```ts
|
|
34
37
|
* const elements = fetch([...]); // Promise<[-3, -1, 0, 2, 3, 5, 6, 8]>;
|
|
35
38
|
* const results = new SmartAsyncIterator(elements)
|
|
@@ -39,6 +42,8 @@ import type { MaybeAsyncKeyedIteratee, MaybeAsyncKeyedReducer } from "./types.js
|
|
|
39
42
|
* console.log(await results.toObject()); // { odd: 4, even: 4 }
|
|
40
43
|
* ```
|
|
41
44
|
*
|
|
45
|
+
* ---
|
|
46
|
+
*
|
|
42
47
|
* @template K The type of the keys used to group the elements.
|
|
43
48
|
* @template T The type of the elements to aggregate.
|
|
44
49
|
*/
|
|
@@ -22,6 +22,9 @@ import type { KeyedIteratee, KeyedTypeGuardPredicate, KeyedReducer } from "./typ
|
|
|
22
22
|
* This is particularly useful when you need to group elements and
|
|
23
23
|
* then perform specific operations on the groups themselves.
|
|
24
24
|
*
|
|
25
|
+
* ---
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
25
28
|
* ```ts
|
|
26
29
|
* const results = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8])
|
|
27
30
|
* .groupBy((value) => value % 2 === 0 ? "even" : "odd")
|
|
@@ -30,6 +33,8 @@ import type { KeyedIteratee, KeyedTypeGuardPredicate, KeyedReducer } from "./typ
|
|
|
30
33
|
* console.log(results.toObject()); // { odd: 4, even: 4 }
|
|
31
34
|
* ```
|
|
32
35
|
*
|
|
36
|
+
* ---
|
|
37
|
+
*
|
|
33
38
|
* @template K The type of the keys used to group the elements.
|
|
34
39
|
* @template T The type of the elements to aggregate.
|
|
35
40
|
*/
|
|
@@ -24,6 +24,9 @@ import type { KeyedIteratee, KeyedReducer, KeyedTypeGuardPredicate } from "./typ
|
|
|
24
24
|
* This is particularly useful when you have group elements and
|
|
25
25
|
* need perform specific operations on the reduced elements.
|
|
26
26
|
*
|
|
27
|
+
* ---
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
27
30
|
* ```ts
|
|
28
31
|
* const results = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8])
|
|
29
32
|
* .groupBy((value) => value % 2 === 0 ? "even" : "odd")
|
|
@@ -32,6 +35,8 @@ import type { KeyedIteratee, KeyedReducer, KeyedTypeGuardPredicate } from "./typ
|
|
|
32
35
|
* console.log(results.toObject()); // { odd: 4, even: 4 }
|
|
33
36
|
* ```
|
|
34
37
|
*
|
|
38
|
+
* ---
|
|
39
|
+
*
|
|
35
40
|
* @template K The type of the key used to group the elements.
|
|
36
41
|
* @template T The type of the elements in the iterator.
|
|
37
42
|
*/
|
|
@@ -508,7 +513,9 @@ export default class ReducedIterator<K extends PropertyKey, T>
|
|
|
508
513
|
*
|
|
509
514
|
* console.log(results.toObject()); // { even: [0, 2, 6, 8] }
|
|
510
515
|
* ```
|
|
511
|
-
*
|
|
516
|
+
*
|
|
517
|
+
* ---
|
|
518
|
+
*
|
|
512
519
|
* @param count The number of elements to drop.
|
|
513
520
|
*
|
|
514
521
|
* @returns A new {@link ReducedIterator} containing the remaining elements.
|
|
@@ -597,9 +604,12 @@ export default class ReducedIterator<K extends PropertyKey, T>
|
|
|
597
604
|
* .groupBy((value) => value % 2 === 0 ? "even" : "odd")
|
|
598
605
|
* .reduce((key, accumulator, value) => accumulator + value)
|
|
599
606
|
* .find((key, value) => value > 0);
|
|
600
|
-
*
|
|
607
|
+
*
|
|
601
608
|
* console.log(results); // 16
|
|
602
|
-
*
|
|
609
|
+
* ```
|
|
610
|
+
*
|
|
611
|
+
* ---
|
|
612
|
+
*
|
|
603
613
|
* @param predicate The condition to check for each element of the iterator.
|
|
604
614
|
*
|
|
605
615
|
* @returns The first element that satisfies the condition, `undefined` otherwise.
|
|
@@ -628,8 +638,11 @@ export default class ReducedIterator<K extends PropertyKey, T>
|
|
|
628
638
|
* .groupBy((value) => Number(value) % 2 === 0 ? "even" : "odd")
|
|
629
639
|
* .reduce((key, accumulator, value) => accumulator + value)
|
|
630
640
|
* .find<number>((key, value) => typeof value === "number");
|
|
631
|
-
*
|
|
641
|
+
*
|
|
632
642
|
* console.log(results); // 16
|
|
643
|
+
* ```
|
|
644
|
+
*
|
|
645
|
+
* ---
|
|
633
646
|
*
|
|
634
647
|
* @template S
|
|
635
648
|
* The type of the elements that satisfy the condition.
|
|
@@ -771,7 +784,7 @@ export default class ReducedIterator<K extends PropertyKey, T>
|
|
|
771
784
|
* const reduced = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8])
|
|
772
785
|
* .groupBy((value) => value % 2 === 0 ? "even" : "odd")
|
|
773
786
|
* .reduce((key, accumulator, value) => accumulator + value);
|
|
774
|
-
*
|
|
787
|
+
*
|
|
775
788
|
* reduced.forEach((key, value, index) =>
|
|
776
789
|
* {
|
|
777
790
|
* console.log(`#${index} - ${key}: ${value}`); // "#0 - odd: 4", "#1 - even: 16"
|
|
@@ -5,6 +5,9 @@ import type { MaybePromise } from "../promises/types.js";
|
|
|
5
5
|
* with the addition of a `key` parameter, compared to the JavaScript's standard ones.
|
|
6
6
|
* It can be used to transform the elements of an aggregated iterable.
|
|
7
7
|
*
|
|
8
|
+
* ---
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
8
11
|
* ```ts
|
|
9
12
|
* const iteratee: KeyedIteratee<string, number, string> = (key: string, value: number) => `${value}`;
|
|
10
13
|
* const results = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8])
|
|
@@ -14,6 +17,8 @@ import type { MaybePromise } from "../promises/types.js";
|
|
|
14
17
|
* console.log(results.toObject()); // { odd: ["-3", "-1", "3", "5"], even: ["0", "2", "6", "8"] }
|
|
15
18
|
* ```
|
|
16
19
|
*
|
|
20
|
+
* ---
|
|
21
|
+
*
|
|
17
22
|
* @template K The type of the key used to aggregate elements in the iterable.
|
|
18
23
|
* @template T The type of the elements in the iterable.
|
|
19
24
|
* @template R The type of the return value of the iteratee. Default is `void`.
|
|
@@ -25,6 +30,9 @@ export type KeyedIteratee<K extends PropertyKey, T, R = void> = (key: K, value:
|
|
|
25
30
|
* function with the addition of a `key` parameter.
|
|
26
31
|
* It can be used to transform the elements of an aggregated iterable asynchronously.
|
|
27
32
|
*
|
|
33
|
+
* ---
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
28
36
|
* ```ts
|
|
29
37
|
* const iteratee: AsyncKeyedIteratee<string, number, string> = async (key: string, value: number) => `${value}`;
|
|
30
38
|
* const results = new SmartAsyncIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8])
|
|
@@ -34,6 +42,8 @@ export type KeyedIteratee<K extends PropertyKey, T, R = void> = (key: K, value:
|
|
|
34
42
|
* console.log(await results.toObject()); // { odd: ["-3", "-1", "3", "5"], even: ["0", "2", "6", "8"] }
|
|
35
43
|
* ```
|
|
36
44
|
*
|
|
45
|
+
* ---
|
|
46
|
+
*
|
|
37
47
|
* @template K The type of the key used to aggregate elements in the iterable.
|
|
38
48
|
* @template T The type of the elements in the iterable.
|
|
39
49
|
* @template R The type of the return value of the iteratee. Default is `void`.
|
|
@@ -45,6 +55,9 @@ export type AsyncKeyedIteratee<K extends PropertyKey, T, R = void> = (key: K, va
|
|
|
45
55
|
* with the addition of a `key` parameter that can be either synchronous or asynchronous.
|
|
46
56
|
* It can be used to transform the elements of an aggregated iterable.
|
|
47
57
|
*
|
|
58
|
+
* ---
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
48
61
|
* ```ts
|
|
49
62
|
* const iteratee: AsyncKeyedIteratee<string, number, string> = [async] (key: string, value: number) => `${value}`;
|
|
50
63
|
* const results = new SmartAsyncIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8])
|
|
@@ -54,6 +67,8 @@ export type AsyncKeyedIteratee<K extends PropertyKey, T, R = void> = (key: K, va
|
|
|
54
67
|
* console.log(await results.toObject()); // { odd: ["-3", "-1", "3", "5"], even: ["0", "2", "6", "8"] }
|
|
55
68
|
* ```
|
|
56
69
|
*
|
|
70
|
+
* ---
|
|
71
|
+
*
|
|
57
72
|
* @template K The type of the key used to aggregate elements in the iterable.
|
|
58
73
|
* @template T The type of the elements in the iterable.
|
|
59
74
|
* @template R The type of the return value of the iteratee. Default is `void`.
|
|
@@ -69,6 +84,9 @@ export type MaybeAsyncKeyedIteratee<K extends PropertyKey, T, R = void> =
|
|
|
69
84
|
* It can be used to filter the elements of an aggregated iterable
|
|
70
85
|
* while allowing the type-system to infer them correctly.
|
|
71
86
|
*
|
|
87
|
+
* ---
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
72
90
|
* ```ts
|
|
73
91
|
* const predicate: KeyedTypeGuardPredicate<string, number | string, string> =
|
|
74
92
|
* (key: string, value: number | string): value is string => typeof value === "string";
|
|
@@ -80,6 +98,8 @@ export type MaybeAsyncKeyedIteratee<K extends PropertyKey, T, R = void> =
|
|
|
80
98
|
* console.log(results.toObject()); // { odd: ["0", "5", "8"], even: [] }
|
|
81
99
|
* ```
|
|
82
100
|
*
|
|
101
|
+
* ---
|
|
102
|
+
*
|
|
83
103
|
* @template K The type of the key used to aggregate elements in the iterable.
|
|
84
104
|
* @template T The type of the elements in the iterable.
|
|
85
105
|
* @template R
|
|
@@ -100,6 +120,9 @@ export type KeyedTypeGuardPredicate<K extends PropertyKey, T, R extends T> =
|
|
|
100
120
|
* An utility type that represents a reducer-like function.
|
|
101
121
|
* It can be used to reduce the elements of an aggregated iterable into a single value.
|
|
102
122
|
*
|
|
123
|
+
* ---
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
103
126
|
* ```ts
|
|
104
127
|
* const sum: KeyedReducer<string, number, number> =
|
|
105
128
|
* (key: string, accumulator: number, value: number) => accumulator + value;
|
|
@@ -111,6 +134,8 @@ export type KeyedTypeGuardPredicate<K extends PropertyKey, T, R extends T> =
|
|
|
111
134
|
* console.log(results.toObject()); // { odd: 4, even: 16 }
|
|
112
135
|
* ```
|
|
113
136
|
*
|
|
137
|
+
* ---
|
|
138
|
+
*
|
|
114
139
|
* @template K The type of the key used to aggregate elements in the iterable.
|
|
115
140
|
* @template T The type of the elements in the iterable.
|
|
116
141
|
* @template A The type of the accumulator.
|
|
@@ -121,6 +146,9 @@ export type KeyedReducer<K extends PropertyKey, T, A> = (key: K, accumulator: A,
|
|
|
121
146
|
* An utility type that represents an asynchronous reducer-like function.
|
|
122
147
|
* It can be used to reduce the elements of an aggregated iterable into a single value.
|
|
123
148
|
*
|
|
149
|
+
* ---
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
124
152
|
* ```ts
|
|
125
153
|
* const sum: AsyncKeyedReducer<string, number, number> =
|
|
126
154
|
* async (key: string, accumulator: number, value: number) => accumulator + value;
|
|
@@ -132,6 +160,8 @@ export type KeyedReducer<K extends PropertyKey, T, A> = (key: K, accumulator: A,
|
|
|
132
160
|
* console.log(await results.toObject()); // { odd: 4, even: 16 }
|
|
133
161
|
* ```
|
|
134
162
|
*
|
|
163
|
+
* ---
|
|
164
|
+
*
|
|
135
165
|
* @template K The type of the key used to aggregate elements in the iterable.
|
|
136
166
|
* @template T The type of the elements in the iterable.
|
|
137
167
|
* @template A The type of the accumulator.
|
|
@@ -143,6 +173,9 @@ export type AsyncKeyedReducer<K extends PropertyKey, T, A> =
|
|
|
143
173
|
* An utility type that represents a reducer-like function that can be either synchronous or asynchronous.
|
|
144
174
|
* It can be used to reduce the elements of an aggregated iterable into a single value.
|
|
145
175
|
*
|
|
176
|
+
* ---
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
146
179
|
* ```ts
|
|
147
180
|
* const sum: MaybeAsyncKeyedReducer<string, number, number> =
|
|
148
181
|
* [async] (key: string, accumulator: number, value: number) => accumulator + value;
|
|
@@ -154,6 +187,8 @@ export type AsyncKeyedReducer<K extends PropertyKey, T, A> =
|
|
|
154
187
|
* console.log(await results.toObject()); // { odd: 4, even: 16 }
|
|
155
188
|
* ```
|
|
156
189
|
*
|
|
190
|
+
* ---
|
|
191
|
+
*
|
|
157
192
|
* @template K The type of the key used to aggregate elements in the iterable.
|
|
158
193
|
* @template T The type of the elements in the iterable.
|
|
159
194
|
* @template A The type of the accumulator.
|
|
@@ -8,6 +8,9 @@ const SmartFunction = (Function as unknown) as new<A extends unknown[] = [], R =
|
|
|
8
8
|
/**
|
|
9
9
|
* An abstract class that can be used to implement callable objects.
|
|
10
10
|
*
|
|
11
|
+
* ---
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
11
14
|
* ```ts
|
|
12
15
|
* class ActivableCallback extends CallableObject<(evt: PointerEvent) => void>
|
|
13
16
|
* {
|
|
@@ -25,6 +28,8 @@ const SmartFunction = (Function as unknown) as new<A extends unknown[] = [], R =
|
|
|
25
28
|
* window.addEventListener("pointerup", () => { callback.enabled = false; });
|
|
26
29
|
* ```
|
|
27
30
|
*
|
|
31
|
+
* ---
|
|
32
|
+
*
|
|
28
33
|
* @template T
|
|
29
34
|
* The type signature of the callback function.
|
|
30
35
|
* It must be a function. Default is `(...args: any[]) => any`.
|
|
@@ -49,6 +54,8 @@ export default abstract class CallableObject<T extends Callback<any[], any> = ()
|
|
|
49
54
|
* The method that will be called when the object is invoked.
|
|
50
55
|
* It must be implemented by the derived classes.
|
|
51
56
|
*
|
|
57
|
+
* ---
|
|
58
|
+
*
|
|
52
59
|
* @param args The arguments that have been passed to the object.
|
|
53
60
|
*
|
|
54
61
|
* @returns The return value of the method.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReferenceException } from "../exceptions/index.js";
|
|
2
2
|
|
|
3
|
-
import type { Callback } from "./types.js";
|
|
3
|
+
import type { Callback, CallbackMap } from "./types.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* A class implementing the
|
|
@@ -12,6 +12,9 @@ import type { Callback } from "./types.js";
|
|
|
12
12
|
*
|
|
13
13
|
* Using generics, it's also possible to define the type of the events and the callbacks that can be subscribed to them.
|
|
14
14
|
*
|
|
15
|
+
* ---
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
15
18
|
* ```ts
|
|
16
19
|
* interface EventsMap
|
|
17
20
|
* {
|
|
@@ -30,13 +33,14 @@ import type { Callback } from "./types.js";
|
|
|
30
33
|
* });
|
|
31
34
|
* ```
|
|
32
35
|
*
|
|
36
|
+
* ---
|
|
37
|
+
*
|
|
33
38
|
* @template T
|
|
34
39
|
* A map containing the names of the emittable events and the
|
|
35
40
|
* related callback signatures that can be subscribed to them.
|
|
36
|
-
* Default is `Record<string, () =>
|
|
41
|
+
* Default is `Record<string, (...args: unknown[]) => unknown>`.
|
|
37
42
|
*/
|
|
38
|
-
|
|
39
|
-
export default class Publisher<T extends { [K in keyof T]: Callback<any[], any> } = Record<string, Callback>>
|
|
43
|
+
export default class Publisher<T extends CallbackMap<T> = CallbackMap>
|
|
40
44
|
{
|
|
41
45
|
/**
|
|
42
46
|
* A map containing all the subscribers for each event.
|
|
@@ -44,7 +48,7 @@ export default class Publisher<T extends { [K in keyof T]: Callback<any[], any>
|
|
|
44
48
|
* The keys are the names of the events they are subscribed to.
|
|
45
49
|
* The values are the arrays of the subscribers themselves.
|
|
46
50
|
*/
|
|
47
|
-
protected _subscribers: Map<
|
|
51
|
+
protected _subscribers: Map<string, Callback<unknown[], unknown>[]>;
|
|
48
52
|
|
|
49
53
|
/**
|
|
50
54
|
* Initializes a new instance of the {@link Publisher} class.
|
|
@@ -109,7 +113,7 @@ export default class Publisher<T extends { [K in keyof T]: Callback<any[], any>
|
|
|
109
113
|
*
|
|
110
114
|
* @returns An array containing the return values of all the subscribers.
|
|
111
115
|
*/
|
|
112
|
-
public publish<K extends keyof T>(event: K, ...args: Parameters<T[K]>): ReturnType<T[K]>[]
|
|
116
|
+
public publish<K extends keyof T>(event: K & string, ...args: Parameters<T[K]>): ReturnType<T[K]>[]
|
|
113
117
|
{
|
|
114
118
|
const subscribers = this._subscribers.get(event);
|
|
115
119
|
if (!(subscribers)) { return []; }
|
|
@@ -119,7 +123,7 @@ export default class Publisher<T extends { [K in keyof T]: Callback<any[], any>
|
|
|
119
123
|
}
|
|
120
124
|
|
|
121
125
|
/**
|
|
122
|
-
* Subscribes a
|
|
126
|
+
* Subscribes to an event and adds a subscriber to be executed when the event is published.
|
|
123
127
|
*
|
|
124
128
|
* ---
|
|
125
129
|
*
|
|
@@ -138,11 +142,11 @@ export default class Publisher<T extends { [K in keyof T]: Callback<any[], any>
|
|
|
138
142
|
* @template K The key of the map containing the callback signature to subscribe.
|
|
139
143
|
*
|
|
140
144
|
* @param event The name of the event to subscribe to.
|
|
141
|
-
* @param subscriber The subscriber to
|
|
145
|
+
* @param subscriber The subscriber to execute when the event is published.
|
|
142
146
|
*
|
|
143
|
-
* @returns A function that can be used to unsubscribe the subscriber.
|
|
147
|
+
* @returns A function that can be used to unsubscribe the subscriber from the event.
|
|
144
148
|
*/
|
|
145
|
-
public subscribe<K extends keyof T>(event: K, subscriber: T[K]): () => void
|
|
149
|
+
public subscribe<K extends keyof T>(event: K & string, subscriber: T[K]): () => void
|
|
146
150
|
{
|
|
147
151
|
if (!(this._subscribers.has(event))) { this._subscribers.set(event, []); }
|
|
148
152
|
|
|
@@ -163,7 +167,7 @@ export default class Publisher<T extends { [K in keyof T]: Callback<any[], any>
|
|
|
163
167
|
}
|
|
164
168
|
|
|
165
169
|
/**
|
|
166
|
-
* Unsubscribes a subscriber from
|
|
170
|
+
* Unsubscribes from an event and removes a subscriber from being executed when the event is published.
|
|
167
171
|
*
|
|
168
172
|
* ---
|
|
169
173
|
*
|
|
@@ -182,7 +186,7 @@ export default class Publisher<T extends { [K in keyof T]: Callback<any[], any>
|
|
|
182
186
|
* @param event The name of the event to unsubscribe from.
|
|
183
187
|
* @param subscriber The subscriber to remove from the event.
|
|
184
188
|
*/
|
|
185
|
-
public unsubscribe<K extends keyof T>(event: K, subscriber: T[K]): void
|
|
189
|
+
public unsubscribe<K extends keyof T>(event: K & string, subscriber: T[K]): void
|
|
186
190
|
{
|
|
187
191
|
const subscribers = this._subscribers.get(event);
|
|
188
192
|
if (!(subscribers)) { return; }
|
|
@@ -11,6 +11,9 @@ const Disabler = () => { /* ... */ };
|
|
|
11
11
|
* It can be used to implement different behaviors for the same event handler, allowing
|
|
12
12
|
* it to respond to different states without incurring any overhead during execution.
|
|
13
13
|
*
|
|
14
|
+
* ---
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
14
17
|
* ```ts
|
|
15
18
|
* const onPointerMove = new SwitchableCallback<(evt: PointerEvent) => void>();
|
|
16
19
|
*
|
|
@@ -22,6 +25,8 @@ const Disabler = () => { /* ... */ };
|
|
|
22
25
|
* window.addEventListener("pointerup", () => { onPointerMove.switch("released"); });
|
|
23
26
|
* ```
|
|
24
27
|
*
|
|
28
|
+
* ---
|
|
29
|
+
*
|
|
25
30
|
* @template T The type signature of the callback. Default is `(...args: any[]) => any`.
|
|
26
31
|
*/
|
|
27
32
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -151,7 +156,9 @@ export default class SwitchableCallback<T extends Callback<any[], any> = Callbac
|
|
|
151
156
|
* window.addEventListener("pointerdown", () => { onPointerMove.enable(); });
|
|
152
157
|
* window.addEventListener("pointermove", onPointerMove);
|
|
153
158
|
* ```
|
|
154
|
-
*
|
|
159
|
+
*
|
|
160
|
+
* ---
|
|
161
|
+
*
|
|
155
162
|
* @param key
|
|
156
163
|
* The key that is associated with the implementation to enable. Default is the currently selected implementation.
|
|
157
164
|
*/
|
|
@@ -303,6 +310,7 @@ export default class SwitchableCallback<T extends Callback<any[], any> = Callbac
|
|
|
303
310
|
throw new KeyException(`The key '${key}' doesn't yet have any associated callback.`);
|
|
304
311
|
}
|
|
305
312
|
|
|
313
|
+
if (this._key === key) { return; }
|
|
306
314
|
this._key = key;
|
|
307
315
|
|
|
308
316
|
if (this._isEnabled)
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2
|
+
import type Publisher from "./publisher.js";
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* A type that represents a generic function.
|
|
3
6
|
*
|
|
4
7
|
* It can be used to define the signature of a callback, a event handler or any other function.
|
|
5
8
|
* It's simply a shorthand for the `(...args: A) => R` function signature.
|
|
6
9
|
*
|
|
10
|
+
* ---
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
7
13
|
* ```ts
|
|
8
14
|
* const callback: Callback<[PointerEvent]> = (evt: PointerEvent): void => { [...] };
|
|
9
15
|
* ```
|
|
10
16
|
*
|
|
17
|
+
* ---
|
|
18
|
+
*
|
|
11
19
|
* @template A
|
|
12
20
|
* The type of the arguments that the function accepts.
|
|
13
21
|
* It must be an array of types, even if it's empty. Default is `[]`.
|
|
@@ -15,3 +23,30 @@
|
|
|
15
23
|
* @template R The return type of the function. Default is `void`.
|
|
16
24
|
*/
|
|
17
25
|
export type Callback<A extends unknown[] = [], R = void> = (...args: A) => R;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* An utility type that is required to represents a map of callbacks.
|
|
29
|
+
*
|
|
30
|
+
* It is used for type inheritance on the {@link Publisher} class signature.
|
|
31
|
+
* Whenever you'll need to extend that class, you may need to use this type too.
|
|
32
|
+
*
|
|
33
|
+
* ---
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* interface EventsMap
|
|
38
|
+
* {
|
|
39
|
+
* "player:spawn": (evt: SpawnEvent) => void;
|
|
40
|
+
* "player:move": ({ x, y }: Point) => void;
|
|
41
|
+
* "player:death": () => void;
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* class EventManager<T extends CallbackMap<T> = { }> extends Publisher<T> { [...] }
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* ---
|
|
48
|
+
*
|
|
49
|
+
* @template T The interface defining the map of callbacks. Default is `Record<string, Callback<unknown[], unknown>>`.
|
|
50
|
+
*/
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
52
|
+
export type CallbackMap<T = Record<string, Callback<unknown[], unknown>>> = { [K in keyof T]: Callback<any[], any> };
|