@byloth/core 2.1.4 → 2.1.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/dist/core.cjs +2 -2
- package/dist/core.cjs.map +1 -1
- package/dist/core.esm.js +218 -163
- package/dist/core.esm.js.map +1 -1
- package/dist/core.global.js +2 -2
- package/dist/core.global.js.map +1 -1
- package/dist/core.umd.cjs +2 -2
- package/dist/core.umd.cjs.map +1 -1
- package/package.json +3 -3
- package/src/core/types.ts +1 -1
- package/src/index.ts +2 -1
- package/src/models/callbacks/publisher.ts +4 -0
- package/src/models/index.ts +1 -1
- package/src/models/promises/index.ts +2 -1
- package/src/models/promises/promise-queue.ts +222 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@byloth/core",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.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",
|
|
@@ -51,9 +51,9 @@
|
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@byloth/eslint-config-typescript": "^3.1.0",
|
|
53
53
|
"@eslint/compat": "^1.3.0",
|
|
54
|
-
"@types/node": "^22.15.
|
|
54
|
+
"@types/node": "^22.15.32",
|
|
55
55
|
"@vitest/coverage-v8": "^3.2.3",
|
|
56
|
-
"eslint": "^9.
|
|
56
|
+
"eslint": "^9.29.0",
|
|
57
57
|
"husky": "^9.1.7",
|
|
58
58
|
"jsdom": "^26.1.0",
|
|
59
59
|
"typescript": "^5.8.3",
|
package/src/core/types.ts
CHANGED
|
@@ -74,7 +74,7 @@ export type Timeout = ReturnType<typeof setTimeout>;
|
|
|
74
74
|
* public greet() { console.log("Hello, world!"); }
|
|
75
75
|
* }
|
|
76
76
|
*
|
|
77
|
-
* type MyObjectProperties = ValueOf<MyObject>;
|
|
77
|
+
* type MyObjectProperties = ValueOf<MyObject>; // number | (() => void)
|
|
78
78
|
* ```
|
|
79
79
|
*
|
|
80
80
|
* ---
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const VERSION = "2.1.
|
|
1
|
+
export const VERSION = "2.1.5";
|
|
2
2
|
|
|
3
3
|
export type { Constructor, Interval, Timeout, ValueOf } from "./core/types.js";
|
|
4
4
|
|
|
@@ -24,6 +24,7 @@ export {
|
|
|
24
24
|
NotImplementedException,
|
|
25
25
|
NetworkException,
|
|
26
26
|
PermissionException,
|
|
27
|
+
PromiseQueue,
|
|
27
28
|
Publisher,
|
|
28
29
|
RangeException,
|
|
29
30
|
ReducedIterator,
|
|
@@ -125,6 +125,10 @@ export default class Publisher<T extends CallbackMap<T> = CallbackMap, W extends
|
|
|
125
125
|
* Default is `T`.
|
|
126
126
|
*
|
|
127
127
|
* @template X An utility type that extends the `U` map with a wildcard event.
|
|
128
|
+
*
|
|
129
|
+
* @return
|
|
130
|
+
* A new instance of the {@link Publisher} class that can be
|
|
131
|
+
* used to publish and subscribe events within a specific context.
|
|
128
132
|
*/
|
|
129
133
|
public createScope<U extends T = T, X extends WithWildcard<U> = WithWildcard<U>>(): Publisher<U, X>
|
|
130
134
|
{
|
package/src/models/index.ts
CHANGED
|
@@ -29,5 +29,5 @@ export {
|
|
|
29
29
|
|
|
30
30
|
export { SmartIterator, SmartAsyncIterator } from "./iterators/index.js";
|
|
31
31
|
export { JSONStorage } from "./json/index.js";
|
|
32
|
-
export { DeferredPromise, SmartPromise, TimedPromise } from "./promises/index.js";
|
|
32
|
+
export { DeferredPromise, PromiseQueue, SmartPromise, TimedPromise } from "./promises/index.js";
|
|
33
33
|
export { Clock, Countdown, GameLoop } from "./timers/index.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import DeferredPromise from "./deferred-promise.js";
|
|
2
|
+
import PromiseQueue from "./promise-queue.js";
|
|
2
3
|
import SmartPromise from "./smart-promise.js";
|
|
3
4
|
import TimedPromise from "./timed-promise.js";
|
|
4
5
|
|
|
5
|
-
export { DeferredPromise, SmartPromise, TimedPromise };
|
|
6
|
+
export { DeferredPromise, PromiseQueue, SmartPromise, TimedPromise };
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import type { Callback } from "../callbacks/types.js";
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4
|
+
import { TimeoutException, ValueException } from "../exceptions/index.js";
|
|
5
|
+
|
|
6
|
+
import DeferredPromise from "./deferred-promise.js";
|
|
7
|
+
import SmartPromise from "./smart-promise.js";
|
|
8
|
+
import TimedPromise from "./timed-promise.js";
|
|
9
|
+
import type { MaybePromise, PromiseRejecter, PromiseResolver } from "./types.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A class that represents a queue of asynchronous operations, allowing them to be executed sequentially.
|
|
13
|
+
*
|
|
14
|
+
* It extends the {@link SmartPromise} class, providing a way to manage multiple promises in a controlled manner.
|
|
15
|
+
* This class is useful for scenarios where you need to ensure
|
|
16
|
+
* that only one asynchronous operation is executed at a time,
|
|
17
|
+
* such as when dealing with API requests, file operations or any other
|
|
18
|
+
* asynchronous tasks that need to be handled in a specific order.
|
|
19
|
+
*
|
|
20
|
+
* ---
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const queue = new PromiseQueue();
|
|
25
|
+
*
|
|
26
|
+
* queue.enqueue(() => new Promise((resolve) => setTimeout(() => resolve("First"), 2000)))
|
|
27
|
+
* queue.enqueue(() => new Promise((resolve) => setTimeout(() => resolve("Second"), 500)))
|
|
28
|
+
* queue.enqueue(() => new Promise((resolve) => setTimeout(() => resolve("Third"), 1000)))
|
|
29
|
+
*
|
|
30
|
+
* await queue; // "First", "Second", "Third"
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export default class PromiseQueue extends SmartPromise<void>
|
|
34
|
+
{
|
|
35
|
+
/**
|
|
36
|
+
* The number of promises currently in the queue.
|
|
37
|
+
*/
|
|
38
|
+
protected _count: number;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A flag indicating whether the promise is still pending or not.
|
|
42
|
+
*/
|
|
43
|
+
public override get isPending(): boolean
|
|
44
|
+
{
|
|
45
|
+
return this._count > 0;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A flag indicating whether the promise has been fulfilled or not.
|
|
49
|
+
*/
|
|
50
|
+
public override get isFulfilled(): boolean
|
|
51
|
+
{
|
|
52
|
+
return this._count === 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A flag indicating whether the promise has been rejected or not.
|
|
57
|
+
*
|
|
58
|
+
* Please note the {@link PromiseQueue} doesn't support rejection states.
|
|
59
|
+
* Accessing this property will always result in a {@link ValueException}.
|
|
60
|
+
*/
|
|
61
|
+
public override get isRejected(): never
|
|
62
|
+
{
|
|
63
|
+
throw new ValueException("`PromiseQueue` doesn't support rejection states.");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The native {@link Promise} object wrapped by this instance.
|
|
68
|
+
*/
|
|
69
|
+
declare protected _promise: Promise<void>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Initializes a new instance of the {@link PromiseQueue} class.
|
|
73
|
+
*/
|
|
74
|
+
public constructor()
|
|
75
|
+
{
|
|
76
|
+
super((resolve) => resolve());
|
|
77
|
+
|
|
78
|
+
this._count = 0;
|
|
79
|
+
|
|
80
|
+
this._isPending = false;
|
|
81
|
+
this._isFulfilled = false;
|
|
82
|
+
this._isRejected = false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Enqueues a {@link DeferredPromise} into the queue.
|
|
87
|
+
*
|
|
88
|
+
* The promise will be executed in sequence after previously enqueued promises.
|
|
89
|
+
*
|
|
90
|
+
* ---
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* const queue = new PromiseQueue();
|
|
95
|
+
* const deferred = new DeferredPromise(() => console.log("Hello, world!"));
|
|
96
|
+
*
|
|
97
|
+
* queue.enqueue(deferred); // "Hello, world!"
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* ---
|
|
101
|
+
*
|
|
102
|
+
* @template T The type of value the promise will eventually resolve to.
|
|
103
|
+
*
|
|
104
|
+
* @param promise A `DeferredPromise<void, T>` instance to enqueue.
|
|
105
|
+
*
|
|
106
|
+
* @returns A {@link Promise} that resolves to the value of the enqueued promise.
|
|
107
|
+
*/
|
|
108
|
+
public enqueue<T>(promise: DeferredPromise<void, T>): Promise<T>;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Enqueues a {@link DeferredPromise} into the queue with an optional timeout.
|
|
112
|
+
*
|
|
113
|
+
* The promise will be executed in sequence after previously enqueued promises.
|
|
114
|
+
* If the promise takes longer than the specified timeout, it will be rejected with a {@link TimeoutException}.
|
|
115
|
+
*
|
|
116
|
+
* ---
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* const queue = new PromiseQueue();
|
|
121
|
+
* const deferred = new DeferredPromise(() => console.log("Hello, world!"));
|
|
122
|
+
*
|
|
123
|
+
* queue.enqueue(deferred, 5000); // "Hello, world!"
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* ---
|
|
127
|
+
*
|
|
128
|
+
* @template T The type of value the promise will eventually resolve to.
|
|
129
|
+
*
|
|
130
|
+
* @param promise A `DeferredPromise<void, T>` instance to enqueue.
|
|
131
|
+
* @param timeout The maximum time in milliseconds that the operation can take before timing out.
|
|
132
|
+
*
|
|
133
|
+
* @returns
|
|
134
|
+
* A {@link TimedPromise} that resolves to the value of the enqueued promise or rejects
|
|
135
|
+
* with a `TimeoutException` if the operation takes longer than the specified timeout.
|
|
136
|
+
*/
|
|
137
|
+
public enqueue<T>(promise: DeferredPromise<void, T>, timeout: number): TimedPromise<T>;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Enqueues a callback that returns a {@link MaybePromise} value of type `T` into the queue.
|
|
141
|
+
*
|
|
142
|
+
* The executor will be executed in sequence after previously enqueued promises.
|
|
143
|
+
*
|
|
144
|
+
* ---
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* const queue = new PromiseQueue();
|
|
149
|
+
*
|
|
150
|
+
* queue.enqueue(() => console.log("Hello, world!")); // "Hello, world!"
|
|
151
|
+
* ```
|
|
152
|
+
*
|
|
153
|
+
* ---
|
|
154
|
+
*
|
|
155
|
+
* @template T The type of value the promise will eventually resolve to.
|
|
156
|
+
*
|
|
157
|
+
* @param executor A callback that returns a `MaybePromise<T>` value to enqueue.
|
|
158
|
+
*
|
|
159
|
+
* @returns A {@link Promise} that resolves to the value of the enqueued executor.
|
|
160
|
+
*/
|
|
161
|
+
public enqueue<T>(executor: Callback<[], MaybePromise<T>>): Promise<T>;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Enqueues a callback that returns a {@link MaybePromise}
|
|
165
|
+
* value of type `T` into the queue with an optional timeout.
|
|
166
|
+
*
|
|
167
|
+
* The executor will be executed in sequence after previously enqueued promises.
|
|
168
|
+
* If the executor takes longer than the specified timeout, it will be rejected with a {@link TimeoutException}.
|
|
169
|
+
*
|
|
170
|
+
* ---
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* const queue = new PromiseQueue();
|
|
175
|
+
*
|
|
176
|
+
* queue.enqueue(() => console.log("Hello, world!"), 5000); // "Hello, world!"
|
|
177
|
+
* ```
|
|
178
|
+
*
|
|
179
|
+
* ---
|
|
180
|
+
*
|
|
181
|
+
* @template T The type of value the promise will eventually resolve to.
|
|
182
|
+
*
|
|
183
|
+
* @param executor A callback that returns a `MaybePromise<T>` value to enqueue.
|
|
184
|
+
* @param timeout The maximum time in milliseconds that the operation can take before timing out.
|
|
185
|
+
*
|
|
186
|
+
* @returns
|
|
187
|
+
* A {@link TimedPromise} that resolves to the value of the enqueued executor or rejects
|
|
188
|
+
* with a `TimeoutException` if the operation takes longer than the specified timeout.
|
|
189
|
+
*/
|
|
190
|
+
public enqueue<T>(executor: Callback<[], MaybePromise<T>>, timeout?: number): TimedPromise<T>;
|
|
191
|
+
public enqueue<T>(executor: DeferredPromise<void, T> | Callback<[], MaybePromise<T>>, timeout?: number)
|
|
192
|
+
: Promise<T> | TimedPromise<T>
|
|
193
|
+
{
|
|
194
|
+
this._count += 1;
|
|
195
|
+
|
|
196
|
+
if (executor instanceof DeferredPromise)
|
|
197
|
+
{
|
|
198
|
+
const _executor = executor as DeferredPromise<void, T>;
|
|
199
|
+
|
|
200
|
+
executor = () =>
|
|
201
|
+
{
|
|
202
|
+
_executor.resolve();
|
|
203
|
+
|
|
204
|
+
return _executor;
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const _executor = (resolve: PromiseResolver<T>, reject: PromiseRejecter) =>
|
|
209
|
+
{
|
|
210
|
+
this._promise = this._promise
|
|
211
|
+
.then(executor)
|
|
212
|
+
.then((value) => { this._count -= 1; resolve(value); })
|
|
213
|
+
.catch((value) => { this._count -= 1; reject(value); });
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
if (timeout) { return new TimedPromise<T>(_executor, timeout); }
|
|
217
|
+
|
|
218
|
+
return new Promise<T>(_executor);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
public override readonly [Symbol.toStringTag]: string = "PromiseQueue";
|
|
222
|
+
}
|