@flex-development/when 2.0.0 → 3.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/CHANGELOG.md +32 -0
- package/README.md +657 -69
- package/dist/index.d.mts +407 -23
- package/dist/lib/index.mjs +4 -1
- package/dist/lib/is-catchable.mjs +24 -0
- package/dist/lib/is-finalizable.mjs +24 -0
- package/dist/lib/is-promise-like.mjs +24 -0
- package/dist/lib/is-promise.mjs +12 -6
- package/dist/lib/is-thenable.mjs +30 -8
- package/dist/lib/when.mjs +76 -12
- package/dist/testing/index.d.mts +149 -0
- package/dist/testing/index.mjs +5 -0
- package/dist/testing/lib/create-thenable.mjs +350 -0
- package/dist/testing/lib/index.mjs +5 -0
- package/package.json +15 -7
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Interfaces - PromiseLike
|
|
3
|
+
* @module when/interfaces/PromiseLike
|
|
4
|
+
*/
|
|
5
|
+
declare global {
|
|
6
|
+
interface PromiseLike<T> {
|
|
7
|
+
/**
|
|
8
|
+
* Attach callbacks for resolution and/or rejection.
|
|
9
|
+
*
|
|
10
|
+
* @template {any} [S=T]
|
|
11
|
+
* The next resolved value on success
|
|
12
|
+
* @template {any} [F=never]
|
|
13
|
+
* The next resolved value on failure
|
|
14
|
+
*
|
|
15
|
+
* @this {unknown}
|
|
16
|
+
*
|
|
17
|
+
* @param {((value: T) => PromiseLike<S> | S) | null | undefined} [succ]
|
|
18
|
+
* The callback to execute when the thenable is resolved
|
|
19
|
+
* @param {((reason: any) => F | PromiseLike<F>) | null | undefined} [fail]
|
|
20
|
+
* The callback to execute when the thenable is rejected
|
|
21
|
+
* @return {PromiseLike<F | S>}
|
|
22
|
+
* The next promise-like object
|
|
23
|
+
*/
|
|
24
|
+
then<S = T, F = never>(succ?: ((value: T) => PromiseLike<S> | S) | null | undefined, fail?: ((reason: any) => F | PromiseLike<F>) | null | undefined): PromiseLike<F | S>;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @file Interfaces - Catchable
|
|
30
|
+
* @module when/interfaces/Catchable
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A thenable that can be caught.
|
|
35
|
+
*
|
|
36
|
+
* @see {@linkcode Thenable}
|
|
37
|
+
*
|
|
38
|
+
* @template {any} [T=any]
|
|
39
|
+
* The resolved value
|
|
40
|
+
*
|
|
41
|
+
* @extends {Thenable<T>}
|
|
42
|
+
*/
|
|
43
|
+
interface Catchable<T = any> extends Thenable<T> {
|
|
44
|
+
/**
|
|
45
|
+
* Attach a callback only to be invoked on rejection.
|
|
46
|
+
*
|
|
47
|
+
* @see {@linkcode Catch}
|
|
48
|
+
*
|
|
49
|
+
* @override
|
|
50
|
+
*/
|
|
51
|
+
catch: Catch<T>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @file Interfaces - Finalizable
|
|
56
|
+
* @module when/interfaces/Finalizable
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* A thenable that can be finalized.
|
|
61
|
+
*
|
|
62
|
+
* @see {@linkcode Thenable}
|
|
63
|
+
*
|
|
64
|
+
* @template {any} [T=any]
|
|
65
|
+
* The resolved value
|
|
66
|
+
*
|
|
67
|
+
* @extends {Thenable<T>}
|
|
68
|
+
*/
|
|
69
|
+
interface Finalizable<T = any> extends Thenable<T> {
|
|
70
|
+
/**
|
|
71
|
+
* Attach a callback only to be invoked
|
|
72
|
+
* on settlement (fulfillment or rejection).
|
|
73
|
+
*
|
|
74
|
+
* > 👉 **Note**: The resolved value cannot be modified from the callback.
|
|
75
|
+
*
|
|
76
|
+
* @see {@linkcode Finally}
|
|
77
|
+
*
|
|
78
|
+
* @override
|
|
79
|
+
*/
|
|
80
|
+
finally: Finally<T>;
|
|
81
|
+
}
|
|
82
|
+
|
|
1
83
|
/**
|
|
2
84
|
* @file Interfaces - Options
|
|
3
85
|
* @module when/interfaces/Options
|
|
@@ -60,8 +142,109 @@ interface Options<T = any, Next = any, Failure = Next, Args extends readonly any
|
|
|
60
142
|
* @since 2.0.0
|
|
61
143
|
*/
|
|
62
144
|
fail?: Fail<Failure, Error, This> | null | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* The callback to invoke after chaining completes, whether the operation
|
|
147
|
+
* succeeds or fails.
|
|
148
|
+
*
|
|
149
|
+
* It runs exactly once after {@linkcode chain} and {@linkcode fail}, cannot
|
|
150
|
+
* affect the resolved value, and does not intercept errors.
|
|
151
|
+
*
|
|
152
|
+
* @see {@linkcode Finish}
|
|
153
|
+
*
|
|
154
|
+
* @since 3.0.0
|
|
155
|
+
*/
|
|
156
|
+
finish?: Finish<This> | null | undefined;
|
|
63
157
|
}
|
|
64
158
|
|
|
159
|
+
/**
|
|
160
|
+
* @file Interfaces - Thenable
|
|
161
|
+
* @module when/interfaces/Thenable
|
|
162
|
+
*/
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* The completion of an asynchronous operation, and the minimal structural
|
|
166
|
+
* contract required by `when` to treat a value as asynchronous.
|
|
167
|
+
*
|
|
168
|
+
* Unlike {@linkcode PromiseLike}, this interface allows maybe-callable `catch`
|
|
169
|
+
* and `finally` methods, which when present, are used by `when` to ensure
|
|
170
|
+
* failures are handled and post-processing hooks are executed without forcing
|
|
171
|
+
* promise allocation.
|
|
172
|
+
*
|
|
173
|
+
* Maybe-callable methods are named so because they are not required,
|
|
174
|
+
* and may be a method implementation, `null`, or `undefined`.
|
|
175
|
+
*
|
|
176
|
+
* @template {any} [T=any]
|
|
177
|
+
* The resolved value
|
|
178
|
+
*/
|
|
179
|
+
interface Thenable<T = any> {
|
|
180
|
+
/**
|
|
181
|
+
* Attach a callback only to be invoked on rejection.
|
|
182
|
+
*
|
|
183
|
+
* @see {@linkcode Catch}
|
|
184
|
+
*/
|
|
185
|
+
catch?: Catch<T> | null | undefined;
|
|
186
|
+
/**
|
|
187
|
+
* Attach a callback only to be invoked
|
|
188
|
+
* on settlement (fulfillment or rejection).
|
|
189
|
+
*
|
|
190
|
+
* > 👉 **Note**: The resolved value cannot be modified from the callback.
|
|
191
|
+
*
|
|
192
|
+
* @see {@linkcode Finally}
|
|
193
|
+
*/
|
|
194
|
+
finally?: Finally<T> | null | undefined;
|
|
195
|
+
/**
|
|
196
|
+
* Attach callbacks to be invoked on resolution (fulfillment)
|
|
197
|
+
* and/or rejection.
|
|
198
|
+
*
|
|
199
|
+
* @see {@linkcode Then}
|
|
200
|
+
*/
|
|
201
|
+
then: Then<T>;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* @file isCatchable
|
|
206
|
+
* @module when/lib/isCatchable
|
|
207
|
+
*/
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Check if `value` looks like a `Thenable` that can be caught.
|
|
211
|
+
*
|
|
212
|
+
* @see {@linkcode Catchable}
|
|
213
|
+
*
|
|
214
|
+
* @template {any} T
|
|
215
|
+
* The resolved value
|
|
216
|
+
*
|
|
217
|
+
* @this {void}
|
|
218
|
+
*
|
|
219
|
+
* @param {unknown} value
|
|
220
|
+
* The thing to check
|
|
221
|
+
* @return {value is Catchable<T>}
|
|
222
|
+
* `true` if `value` is a thenable with a `catch` method, `false` otherwise
|
|
223
|
+
*/
|
|
224
|
+
declare function isCatchable<T>(this: void, value: unknown): value is Catchable<T>;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* @file isFinalizable
|
|
228
|
+
* @module when/lib/isFinalizable
|
|
229
|
+
*/
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Check if `value` looks like a thenable that can be finalized.
|
|
233
|
+
*
|
|
234
|
+
* @see {@linkcode Finalizable}
|
|
235
|
+
*
|
|
236
|
+
* @template {any} T
|
|
237
|
+
* The resolved value
|
|
238
|
+
*
|
|
239
|
+
* @this {void}
|
|
240
|
+
*
|
|
241
|
+
* @param {unknown} value
|
|
242
|
+
* The thing to check
|
|
243
|
+
* @return {value is Finalizable<T>}
|
|
244
|
+
* `true` if `value` is a thenable with a `finally` method, `false` otherwise
|
|
245
|
+
*/
|
|
246
|
+
declare function isFinalizable<T>(this: void, value: unknown): value is Finalizable<T>;
|
|
247
|
+
|
|
65
248
|
/**
|
|
66
249
|
* @file isPromise
|
|
67
250
|
* @module when/lib/isPromise
|
|
@@ -69,8 +252,8 @@ interface Options<T = any, Next = any, Failure = Next, Args extends readonly any
|
|
|
69
252
|
/**
|
|
70
253
|
* Check if `value` looks like a {@linkcode Promise}.
|
|
71
254
|
*
|
|
72
|
-
* > 👉 **Note**: This function intentionally performs
|
|
73
|
-
* > instead of
|
|
255
|
+
* > 👉 **Note**: This function intentionally performs structural checks
|
|
256
|
+
* > instead of brand checks.
|
|
74
257
|
* > It does not rely on `instanceof Promise` or constructors, making it
|
|
75
258
|
* > compatible with cross-realm promises and custom thenables.
|
|
76
259
|
*
|
|
@@ -83,18 +266,21 @@ interface Options<T = any, Next = any, Failure = Next, Args extends readonly any
|
|
|
83
266
|
*
|
|
84
267
|
* @param {unknown} value
|
|
85
268
|
* The thing to check
|
|
269
|
+
* @param {boolean | null | undefined} [finalizable=true]
|
|
270
|
+
* Whether a `finally` method is required.\
|
|
271
|
+
* When `false`, only `then` and `catch` are checked
|
|
86
272
|
* @return {value is Promise<T>}
|
|
87
|
-
* `true` if `value` is a thenable with a `catch` method,
|
|
273
|
+
* `true` if `value` is a thenable with a `catch` method,
|
|
274
|
+
* and `finally` method (if requested), `false` otherwise
|
|
88
275
|
*/
|
|
89
|
-
declare function isPromise<T>(this: void, value: unknown): value is Promise<T>;
|
|
276
|
+
declare function isPromise<T>(this: void, value: unknown, finalizable?: boolean | null | undefined): value is Promise<T>;
|
|
90
277
|
|
|
91
278
|
/**
|
|
92
|
-
* @file
|
|
93
|
-
* @module when/lib/
|
|
279
|
+
* @file isPromiseLike
|
|
280
|
+
* @module when/lib/isPromiseLike
|
|
94
281
|
*/
|
|
95
282
|
/**
|
|
96
|
-
* Check if `value` looks like a
|
|
97
|
-
* i.e. a {@linkcode PromiseLike} object.
|
|
283
|
+
* Check if `value` looks like a {@linkcode PromiseLike} structure.
|
|
98
284
|
*
|
|
99
285
|
* @template {any} T
|
|
100
286
|
* The resolved value
|
|
@@ -107,7 +293,30 @@ declare function isPromise<T>(this: void, value: unknown): value is Promise<T>;
|
|
|
107
293
|
* `true` if `value` is an object or function with a `then` method,
|
|
108
294
|
* `false` otherwise
|
|
109
295
|
*/
|
|
110
|
-
declare function
|
|
296
|
+
declare function isPromiseLike<T>(this: void, value: unknown): value is PromiseLike<T>;
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* @file isThenable
|
|
300
|
+
* @module when/lib/isThenable
|
|
301
|
+
*/
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Check if `value` looks like a {@linkcode Thenable}.
|
|
305
|
+
*
|
|
306
|
+
* @see {@linkcode Thenable}
|
|
307
|
+
*
|
|
308
|
+
* @template {any} T
|
|
309
|
+
* The resolved value
|
|
310
|
+
*
|
|
311
|
+
* @this {void}
|
|
312
|
+
*
|
|
313
|
+
* @param {unknown} value
|
|
314
|
+
* The thing to check
|
|
315
|
+
* @return {value is Thenable<T>}
|
|
316
|
+
* `true` if `value` is an object or function with a `then` method,
|
|
317
|
+
* and maybe-callable methods `catch` and/or `finally`, `false` otherwise
|
|
318
|
+
*/
|
|
319
|
+
declare function isThenable<T>(this: void, value: unknown): value is Thenable<T>;
|
|
111
320
|
|
|
112
321
|
/**
|
|
113
322
|
* @file when
|
|
@@ -130,6 +339,8 @@ declare function isThenable<T>(this: void, value: unknown): value is PromiseLike
|
|
|
130
339
|
* The chain function arguments
|
|
131
340
|
* @template {any} [This=any]
|
|
132
341
|
* The `this` context
|
|
342
|
+
* @template {Awaitable<Next>} [Result=Awaitable<Next>]
|
|
343
|
+
* The next awaitable
|
|
133
344
|
*
|
|
134
345
|
* @this {void}
|
|
135
346
|
*
|
|
@@ -143,10 +354,10 @@ declare function isThenable<T>(this: void, value: unknown): value is PromiseLike
|
|
|
143
354
|
* The `this` context of the chain and `fail` callbacks
|
|
144
355
|
* @param {Args} args
|
|
145
356
|
* The arguments to pass to the chain callback
|
|
146
|
-
* @return {
|
|
357
|
+
* @return {Result}
|
|
147
358
|
* The next awaitable
|
|
148
359
|
*/
|
|
149
|
-
declare function when<T, Next = any, Args extends any[] = any[], This = unknown>(this: void, value: Awaitable<T>, chain: Chain<T, Next, Args, This>, fail?: null | undefined, context?: This | null | undefined, ...args: Args):
|
|
360
|
+
declare function when<T, Next = any, Args extends any[] = any[], This = unknown, Result extends Awaitable<Next> = Awaitable<Next>>(this: void, value: Awaitable<T>, chain: Chain<T, Next, Args, This>, fail?: null | undefined, context?: This | null | undefined, ...args: Args): Result;
|
|
150
361
|
/**
|
|
151
362
|
* Chain a callback, calling the function after `value` is resolved,
|
|
152
363
|
* or immediately if `value` is not a thenable.
|
|
@@ -167,6 +378,8 @@ declare function when<T, Next = any, Args extends any[] = any[], This = unknown>
|
|
|
167
378
|
* The error to possibly handle
|
|
168
379
|
* @template {any} [This=any]
|
|
169
380
|
* The `this` context
|
|
381
|
+
* @template {Awaitable<Failure | Next>} [Result=Awaitable<Failure | Next>]
|
|
382
|
+
* The next awaitable
|
|
170
383
|
*
|
|
171
384
|
* @this {void}
|
|
172
385
|
*
|
|
@@ -180,10 +393,10 @@ declare function when<T, Next = any, Args extends any[] = any[], This = unknown>
|
|
|
180
393
|
* The `this` context of the chain and `fail` callbacks
|
|
181
394
|
* @param {Args} args
|
|
182
395
|
* The arguments to pass to the chain callback
|
|
183
|
-
* @return {
|
|
396
|
+
* @return {Result}
|
|
184
397
|
* The next awaitable
|
|
185
398
|
*/
|
|
186
|
-
declare function when<T, Next = any, Failure = Next, Args extends any[] = any[], Error = any, This = unknown>(this: void, value: Awaitable<T>, chain: Chain<T, Next, Args, This>, fail?: Fail<Failure, Error, This> | null | undefined, context?: This | null | undefined, ...args: Args):
|
|
399
|
+
declare function when<T, Next = any, Failure = Next, Args extends any[] = any[], Error = any, This = unknown, Result extends Awaitable<Failure | Next> = Awaitable<Failure | Next>>(this: void, value: Awaitable<T>, chain: Chain<T, Next, Args, This>, fail?: Fail<Failure, Error, This> | null | undefined, context?: This | null | undefined, ...args: Args): Result;
|
|
187
400
|
/**
|
|
188
401
|
* Chain a callback, calling the function after `value` is resolved,
|
|
189
402
|
* or immediately if `value` is not a thenable.
|
|
@@ -203,6 +416,8 @@ declare function when<T, Next = any, Failure = Next, Args extends any[] = any[],
|
|
|
203
416
|
* The error to possibly handle
|
|
204
417
|
* @template {any} [This=unknown]
|
|
205
418
|
* The `this` context
|
|
419
|
+
* @template {Awaitable<Failure | Next>} [Result=Awaitable<Failure | Next>]
|
|
420
|
+
* The next awaitable
|
|
206
421
|
*
|
|
207
422
|
* @this {void}
|
|
208
423
|
*
|
|
@@ -210,22 +425,52 @@ declare function when<T, Next = any, Failure = Next, Args extends any[] = any[],
|
|
|
210
425
|
* The current awaitable
|
|
211
426
|
* @param {Options<T, Next, Failure, Args, Error, This>} chain
|
|
212
427
|
* Options for chaining
|
|
213
|
-
* @return {
|
|
428
|
+
* @return {Result}
|
|
214
429
|
* The next awaitable
|
|
215
430
|
*/
|
|
216
|
-
declare function when<T, Next = any, Failure = Next, Args extends any[] = any[], Error = any, This = unknown>(this: void, value: Awaitable<T>, chain: Options<T, Next, Failure, Args, Error, This>):
|
|
431
|
+
declare function when<T, Next = any, Failure = Next, Args extends any[] = any[], Error = any, This = unknown, Result extends Awaitable<Failure | Next> = Awaitable<Failure | Next>>(this: void, value: Awaitable<T>, chain: Options<T, Next, Failure, Args, Error, This>): Result;
|
|
217
432
|
|
|
218
433
|
/**
|
|
219
434
|
* @file Type Aliases - Awaitable
|
|
220
435
|
* @module when/types/Awaitable
|
|
221
436
|
*/
|
|
437
|
+
|
|
222
438
|
/**
|
|
223
439
|
* A synchronous or thenable value.
|
|
224
440
|
*
|
|
441
|
+
* @see {@linkcode Thenable}
|
|
442
|
+
*
|
|
225
443
|
* @template {any} T
|
|
226
444
|
* The resolved value
|
|
227
445
|
*/
|
|
228
|
-
type Awaitable<T> =
|
|
446
|
+
type Awaitable<T> = Thenable<T> | T;
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* @file Type Aliases - Catch
|
|
450
|
+
* @module when/types/Catch
|
|
451
|
+
*/
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Attach a callback only for the rejection of a `Thenable`.
|
|
455
|
+
*
|
|
456
|
+
* @see {@linkcode OnRejected}
|
|
457
|
+
* @see {@linkcode Thenable}
|
|
458
|
+
*
|
|
459
|
+
* @template {any} [T=unknown]
|
|
460
|
+
* The resolved value
|
|
461
|
+
* @template {any} [Reason=any]
|
|
462
|
+
* The reason for the rejection
|
|
463
|
+
* @template {any} [Next=never]
|
|
464
|
+
* The next resolved value
|
|
465
|
+
*
|
|
466
|
+
* @this {any}
|
|
467
|
+
*
|
|
468
|
+
* @param {OnRejected<Next, Reason> | null | undefined} [onrejected]
|
|
469
|
+
* The callback to execute when the thenable is rejected
|
|
470
|
+
* @return {Thenable<Next | T>}
|
|
471
|
+
* The next thenable
|
|
472
|
+
*/
|
|
473
|
+
type Catch<T = unknown, Reason = any> = <Next = never>(this: any, onrejected?: OnRejected<Next, Reason> | null | undefined) => Thenable<Next | T>;
|
|
229
474
|
|
|
230
475
|
/**
|
|
231
476
|
* @file Type Aliases - Chain
|
|
@@ -269,19 +514,158 @@ type Chain<T = any, Next = any, Args extends readonly any[] = any[], This = unkn
|
|
|
269
514
|
*
|
|
270
515
|
* @template {any} [Next=any]
|
|
271
516
|
* The next resolved value
|
|
272
|
-
* @template {any} [
|
|
273
|
-
* The
|
|
517
|
+
* @template {any} [Reason=any]
|
|
518
|
+
* The reason for the failure
|
|
519
|
+
* @template {any} [This=unknown]
|
|
520
|
+
* The `this` context
|
|
521
|
+
*
|
|
522
|
+
* @this {This}
|
|
523
|
+
*
|
|
524
|
+
* @param {Reason} reason
|
|
525
|
+
* The reason for the failure
|
|
526
|
+
* @return {Awaitable<Next>}
|
|
527
|
+
* The next awaitable
|
|
528
|
+
*/
|
|
529
|
+
type Fail<Next = any, Reason = any, This = unknown> = (this: This, reason: Reason) => Awaitable<Next>;
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* @file Type Aliases - Finally
|
|
533
|
+
* @module when/types/Finally
|
|
534
|
+
*/
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Attach a callback that is invoked only when a `Thenable`
|
|
538
|
+
* is settled (fulfilled or rejected).
|
|
539
|
+
*
|
|
540
|
+
* > 👉 **Note**: The resolved value cannot be modified from the callback.
|
|
541
|
+
*
|
|
542
|
+
* @see {@linkcode OnFinally}
|
|
543
|
+
* @see {@linkcode Thenable}
|
|
544
|
+
*
|
|
545
|
+
* @template {any} [T=unknown]
|
|
546
|
+
* The resolved value
|
|
547
|
+
*
|
|
548
|
+
* @this {any}
|
|
549
|
+
*
|
|
550
|
+
* @param {OnFinally | null | undefined} [onfinally]
|
|
551
|
+
* The callback to execute when the thenable is settled
|
|
552
|
+
* @return {Thenable<T>}
|
|
553
|
+
* The next thenable
|
|
554
|
+
*/
|
|
555
|
+
type Finally<T = unknown> = (this: any, onfinally?: OnFinally | null | undefined) => Thenable<T>;
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* @file Type Aliases - Finish
|
|
559
|
+
* @module when/types/Finish
|
|
560
|
+
*/
|
|
561
|
+
/**
|
|
562
|
+
* A post-processing hook invoked exactly once after an awaitable settles,
|
|
563
|
+
* regardless of success or failure.
|
|
564
|
+
*
|
|
565
|
+
* The resolved value cannot be modified from the hook,
|
|
566
|
+
* and any error is re-thrown after execution.
|
|
567
|
+
*
|
|
274
568
|
* @template {any} [This=unknown]
|
|
275
569
|
* The `this` context
|
|
276
570
|
*
|
|
277
571
|
* @this {This}
|
|
278
572
|
*
|
|
279
|
-
* @
|
|
280
|
-
|
|
573
|
+
* @return {undefined | void}
|
|
574
|
+
*/
|
|
575
|
+
type Finish<This = unknown> = (this: This) => undefined | void;
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* @file Type Aliases - OnFinally
|
|
579
|
+
* @module when/types/OnFinally
|
|
580
|
+
*/
|
|
581
|
+
/**
|
|
582
|
+
* The callback to execute when a `Thenable` is settled (fulfilled or rejected).
|
|
583
|
+
*
|
|
584
|
+
* @this {unknown}
|
|
585
|
+
*
|
|
586
|
+
* @return {undefined | void}
|
|
587
|
+
*/
|
|
588
|
+
type OnFinally = (this: unknown) => undefined | void;
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* @file Type Aliases - OnFulfilled
|
|
592
|
+
* @module when/types/OnFulfilled
|
|
593
|
+
*/
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* The callback to execute when a `Thenable` is resolved.
|
|
597
|
+
*
|
|
598
|
+
* @see {@linkcode Awaitable}
|
|
599
|
+
*
|
|
600
|
+
* @template {any} T
|
|
601
|
+
* The resolved value
|
|
602
|
+
* @template {any} [Next=T]
|
|
603
|
+
* The next resolved value
|
|
604
|
+
*
|
|
605
|
+
* @this {unknown}
|
|
606
|
+
*
|
|
607
|
+
* @param {T} value
|
|
608
|
+
* The resolved value
|
|
609
|
+
* @return {Awaitable<Next>}
|
|
610
|
+
* The next awaitable
|
|
611
|
+
*/
|
|
612
|
+
type OnFulfilled<T, Next = T> = (this: unknown, value: T) => Awaitable<Next>;
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* @file Type Aliases - OnRejected
|
|
616
|
+
* @module when/types/OnRejected
|
|
617
|
+
*/
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* The callback to execute when a `Thenable` is rejected.
|
|
621
|
+
*
|
|
622
|
+
* @see {@linkcode Awaitable}
|
|
623
|
+
*
|
|
624
|
+
* @template {any} Next
|
|
625
|
+
* The next resolved value
|
|
626
|
+
* @template {any} [Reason=any]
|
|
627
|
+
* The reason for the rejection
|
|
628
|
+
*
|
|
629
|
+
* @this {unknown}
|
|
630
|
+
*
|
|
631
|
+
* @param {Reason} reason
|
|
632
|
+
* The reason for the rejection
|
|
281
633
|
* @return {Awaitable<Next>}
|
|
282
634
|
* The next awaitable
|
|
283
635
|
*/
|
|
284
|
-
type
|
|
636
|
+
type OnRejected<Next, Reason = any> = (this: unknown, reason: Reason) => Awaitable<Next>;
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* @file Type Aliases - Then
|
|
640
|
+
* @module when/types/Then
|
|
641
|
+
*/
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Attach callbacks for the resolution and/or rejection of a `Thenable`.
|
|
645
|
+
*
|
|
646
|
+
* @see {@linkcode OnFulfilled}
|
|
647
|
+
* @see {@linkcode OnRejected}
|
|
648
|
+
* @see {@linkcode Thenable}
|
|
649
|
+
*
|
|
650
|
+
* @template {any} [T=unknown]
|
|
651
|
+
* The previously resolved value
|
|
652
|
+
* @template {any} [Reason=any]
|
|
653
|
+
* The reason for a rejection
|
|
654
|
+
* @template {any} [Succ=T]
|
|
655
|
+
* The next resolved value on success
|
|
656
|
+
* @template {any} [Fail=never]
|
|
657
|
+
* The next resolved value on failure
|
|
658
|
+
*
|
|
659
|
+
* @this {any}
|
|
660
|
+
*
|
|
661
|
+
* @param {OnFulfilled<T, Succ> | null | undefined} [onfulfilled]
|
|
662
|
+
* The callback to execute when the thenable is resolved
|
|
663
|
+
* @param {OnRejected<Fail, Reason> | null | undefined} [onrejected]
|
|
664
|
+
* The callback to execute when the thenable is rejected
|
|
665
|
+
* @return {Thenable<Fail | Succ>}
|
|
666
|
+
* The next thenable
|
|
667
|
+
*/
|
|
668
|
+
type Then<T = unknown, Reason = any> = <Succ = T, Fail = never>(this: any, onfulfilled?: OnFulfilled<T, Succ> | null | undefined, onrejected?: OnRejected<Fail, Reason> | null | undefined) => Thenable<Fail | Succ>;
|
|
285
669
|
|
|
286
|
-
export { when as default,
|
|
287
|
-
export type { Awaitable, Chain, Fail, Options };
|
|
670
|
+
export { when as default, isCatchable, isFinalizable, isPromise, isPromiseLike, isThenable, when };
|
|
671
|
+
export type { Awaitable, Catch, Catchable, Chain, Fail, Finalizable, Finally, Finish, OnFinally, OnFulfilled, OnRejected, Options, Then, Thenable };
|
package/dist/lib/index.mjs
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
* @file Entry Point - Library
|
|
3
3
|
* @module when/lib
|
|
4
4
|
*/
|
|
5
|
+
export { default as isCatchable } from '#lib/is-catchable';
|
|
6
|
+
export { default as isFinalizable } from '#lib/is-finalizable';
|
|
5
7
|
export { default as isPromise } from '#lib/is-promise';
|
|
6
|
-
export { default as isPromiseLike
|
|
8
|
+
export { default as isPromiseLike } from '#lib/is-promise-like';
|
|
9
|
+
export { default as isThenable } from '#lib/is-thenable';
|
|
7
10
|
export { default as when } from '#lib/when';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file isCatchable
|
|
3
|
+
* @module when/lib/isCatchable
|
|
4
|
+
*/
|
|
5
|
+
import isThenable from '#lib/is-thenable';
|
|
6
|
+
/**
|
|
7
|
+
* Check if `value` looks like a `Thenable` that can be caught.
|
|
8
|
+
*
|
|
9
|
+
* @see {@linkcode Catchable}
|
|
10
|
+
*
|
|
11
|
+
* @template {any} T
|
|
12
|
+
* The resolved value
|
|
13
|
+
*
|
|
14
|
+
* @this {void}
|
|
15
|
+
*
|
|
16
|
+
* @param {unknown} value
|
|
17
|
+
* The thing to check
|
|
18
|
+
* @return {value is Catchable<T>}
|
|
19
|
+
* `true` if `value` is a thenable with a `catch` method, `false` otherwise
|
|
20
|
+
*/
|
|
21
|
+
function isCatchable(value) {
|
|
22
|
+
return isThenable(value) && typeof value.catch === 'function';
|
|
23
|
+
}
|
|
24
|
+
export default isCatchable;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file isFinalizable
|
|
3
|
+
* @module when/lib/isFinalizable
|
|
4
|
+
*/
|
|
5
|
+
import isThenable from '#lib/is-thenable';
|
|
6
|
+
/**
|
|
7
|
+
* Check if `value` looks like a thenable that can be finalized.
|
|
8
|
+
*
|
|
9
|
+
* @see {@linkcode Finalizable}
|
|
10
|
+
*
|
|
11
|
+
* @template {any} T
|
|
12
|
+
* The resolved value
|
|
13
|
+
*
|
|
14
|
+
* @this {void}
|
|
15
|
+
*
|
|
16
|
+
* @param {unknown} value
|
|
17
|
+
* The thing to check
|
|
18
|
+
* @return {value is Finalizable<T>}
|
|
19
|
+
* `true` if `value` is a thenable with a `finally` method, `false` otherwise
|
|
20
|
+
*/
|
|
21
|
+
function isFinalizable(value) {
|
|
22
|
+
return isThenable(value) && typeof value.finally === 'function';
|
|
23
|
+
}
|
|
24
|
+
export default isFinalizable;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file isPromiseLike
|
|
3
|
+
* @module when/lib/isPromiseLike
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Check if `value` looks like a {@linkcode PromiseLike} structure.
|
|
7
|
+
*
|
|
8
|
+
* @template {any} T
|
|
9
|
+
* The resolved value
|
|
10
|
+
*
|
|
11
|
+
* @this {void}
|
|
12
|
+
*
|
|
13
|
+
* @param {unknown} value
|
|
14
|
+
* The thing to check
|
|
15
|
+
* @return {value is PromiseLike<T>}
|
|
16
|
+
* `true` if `value` is an object or function with a `then` method,
|
|
17
|
+
* `false` otherwise
|
|
18
|
+
*/
|
|
19
|
+
function isPromiseLike(value) {
|
|
20
|
+
if (typeof value !== 'function' && typeof value !== 'object')
|
|
21
|
+
return false;
|
|
22
|
+
return !!value && 'then' in value && typeof value.then === 'function';
|
|
23
|
+
}
|
|
24
|
+
export default isPromiseLike;
|
package/dist/lib/is-promise.mjs
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
* @file isPromise
|
|
3
3
|
* @module when/lib/isPromise
|
|
4
4
|
*/
|
|
5
|
+
import isCatchable from '#lib/is-catchable';
|
|
6
|
+
import isFinalizable from '#lib/is-finalizable';
|
|
5
7
|
import isThenable from '#lib/is-thenable';
|
|
6
8
|
/**
|
|
7
9
|
* Check if `value` looks like a {@linkcode Promise}.
|
|
8
10
|
*
|
|
9
|
-
* > 👉 **Note**: This function intentionally performs
|
|
10
|
-
* > instead of
|
|
11
|
+
* > 👉 **Note**: This function intentionally performs structural checks
|
|
12
|
+
* > instead of brand checks.
|
|
11
13
|
* > It does not rely on `instanceof Promise` or constructors, making it
|
|
12
14
|
* > compatible with cross-realm promises and custom thenables.
|
|
13
15
|
*
|
|
@@ -20,12 +22,16 @@ import isThenable from '#lib/is-thenable';
|
|
|
20
22
|
*
|
|
21
23
|
* @param {unknown} value
|
|
22
24
|
* The thing to check
|
|
25
|
+
* @param {boolean | null | undefined} [finalizable=true]
|
|
26
|
+
* Whether a `finally` method is required.\
|
|
27
|
+
* When `false`, only `then` and `catch` are checked
|
|
23
28
|
* @return {value is Promise<T>}
|
|
24
|
-
* `true` if `value` is a thenable with a `catch` method,
|
|
29
|
+
* `true` if `value` is a thenable with a `catch` method,
|
|
30
|
+
* and `finally` method (if requested), `false` otherwise
|
|
25
31
|
*/
|
|
26
|
-
function isPromise(value) {
|
|
27
|
-
if (!isThenable(value))
|
|
32
|
+
function isPromise(value, finalizable) {
|
|
33
|
+
if (!(isThenable(value) && isCatchable(value)))
|
|
28
34
|
return false;
|
|
29
|
-
return
|
|
35
|
+
return finalizable ?? true ? isFinalizable(value) : true;
|
|
30
36
|
}
|
|
31
37
|
export default isPromise;
|