tinkit 0.0.0-stage → 1.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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +135 -2
  3. package/dist/arrays/index.d.ts +1168 -0
  4. package/dist/arrays/index.js +1 -0
  5. package/dist/async/index.d.ts +729 -0
  6. package/dist/async/index.js +1 -0
  7. package/dist/cache/index.d.ts +165 -0
  8. package/dist/cache/index.js +1 -0
  9. package/dist/color/index.d.ts +328 -0
  10. package/dist/color/index.js +1 -0
  11. package/dist/date/index.d.ts +1152 -0
  12. package/dist/date/index.js +1 -0
  13. package/dist/decorators/index.d.ts +313 -0
  14. package/dist/decorators/index.js +1 -0
  15. package/dist/easing/index.d.ts +452 -0
  16. package/dist/easing/index.js +1 -0
  17. package/dist/emitter/index.d.ts +104 -0
  18. package/dist/emitter/index.js +1 -0
  19. package/dist/format/index.d.ts +317 -0
  20. package/dist/format/index.js +1 -0
  21. package/dist/functions/index.d.ts +648 -0
  22. package/dist/functions/index.js +1 -0
  23. package/dist/guards/index.d.ts +1009 -0
  24. package/dist/guards/index.js +1 -0
  25. package/dist/index.d.ts +28 -0
  26. package/dist/index.js +1 -0
  27. package/dist/iterables/index.d.ts +501 -0
  28. package/dist/iterables/index.js +1 -0
  29. package/dist/math/index.d.ts +670 -0
  30. package/dist/math/index.js +1 -0
  31. package/dist/objects/index.d.ts +1308 -0
  32. package/dist/objects/index.js +1 -0
  33. package/dist/random/index.d.ts +184 -0
  34. package/dist/random/index.js +1 -0
  35. package/dist/search/index.d.ts +151 -0
  36. package/dist/search/index.js +1 -0
  37. package/dist/store/index.d.ts +71 -0
  38. package/dist/store/index.js +1 -0
  39. package/dist/strings/index.d.ts +751 -0
  40. package/dist/strings/index.js +3 -0
  41. package/dist/url/index.d.ts +357 -0
  42. package/dist/url/index.js +1 -0
  43. package/dist/utils/assert.d.ts +81 -0
  44. package/dist/utils/assert.js +1 -0
  45. package/dist/utils/index.d.ts +1 -0
  46. package/dist/utils/index.js +0 -0
  47. package/dist/utils/types.d.ts +82 -0
  48. package/dist/utils/types.js +0 -0
  49. package/dist/validate/index.d.ts +409 -0
  50. package/dist/validate/index.js +1 -0
  51. package/llms-full.txt +708 -0
  52. package/llms.txt +42 -0
  53. package/package.json +144 -5
@@ -0,0 +1,729 @@
1
+ import { type MemoizeCache, type Result } from '../functions/index.js';
2
+ import type { AbortSignalLike, AnyFunction, RandomGenerator } from '../utils/index.js';
3
+ export type { Result } from '../functions/index.js';
4
+ /**
5
+ * Error used to reject operations cancelled through an abort signal that carries no `reason`.
6
+ * @example
7
+ * const controller = new AbortController();
8
+ * controller.abort(new AbortError('cancelled by the user'));
9
+ * await sleep(1000, { signal: controller.signal }); // throws AbortError
10
+ * new AbortError().message; // => 'The operation was aborted.'
11
+ */
12
+ export declare class AbortError extends Error {
13
+ name: string;
14
+ /**
15
+ * @param {string} [message='The operation was aborted.'] - The error message
16
+ */
17
+ constructor(message?: string);
18
+ }
19
+ /**
20
+ * Error used by {@link withTimeout} when the wrapped promise does not settle in time.
21
+ * @example
22
+ * try {
23
+ * await withTimeout(new Promise(function () {}), 10);
24
+ * } catch (error) {
25
+ * error instanceof TimeoutError; // => true
26
+ * }
27
+ */
28
+ export declare class TimeoutError extends Error {
29
+ name: string;
30
+ /**
31
+ * @param {string} [message='The operation timed out.'] - The error message
32
+ */
33
+ constructor(message?: string);
34
+ }
35
+ /**
36
+ * A promise together with the functions that settle it.
37
+ * @template T - The resolved value type
38
+ */
39
+ export interface Deferred<T> {
40
+ /** The pending promise. */
41
+ readonly promise: Promise<T>;
42
+ /** Resolves `promise` (no-op once settled). */
43
+ resolve(value: T | PromiseLike<T>): void;
44
+ /** Rejects `promise` (no-op once settled). */
45
+ reject(reason?: unknown): void;
46
+ }
47
+ /**
48
+ * Options accepted by {@link sleep}.
49
+ */
50
+ export interface SleepOptions {
51
+ /** Aborts the sleep, rejecting with the signal's `reason` (or an {@link AbortError}). */
52
+ signal?: AbortSignalLike;
53
+ }
54
+ /**
55
+ * Options accepted by {@link retry}.
56
+ */
57
+ export interface RetryOptions {
58
+ /** Number of retries after the first attempt (`Infinity` allowed). Defaults to `3`. */
59
+ retries?: number;
60
+ /** Delay in ms before the first retry. Defaults to `0`. */
61
+ delay?: number;
62
+ /** Multiplier applied to the delay after each retry. Defaults to `2`. */
63
+ factor?: number;
64
+ /** Upper bound for a single delay in ms. Defaults to `Infinity`. */
65
+ maxDelay?: number;
66
+ /** When `true`, each delay is drawn uniformly from `[0, delay]` ("full jitter"). Defaults to `false`. */
67
+ jitter?: boolean;
68
+ /** Decides whether the error thrown by attempt number `attempt` (1-based) should be retried. Defaults to always. */
69
+ shouldRetry?(error: unknown, attempt: number): boolean;
70
+ /** Called before waiting for the next retry, with the error of attempt number `attempt` (1-based). */
71
+ onRetry?(error: unknown, attempt: number): void;
72
+ /** Aborts the retry loop between attempts (and during delays), rejecting with the signal's reason. */
73
+ signal?: AbortSignalLike;
74
+ }
75
+ /**
76
+ * Creates a promise that can be resolved or rejected from the outside.
77
+ * @template T - The resolved value type
78
+ * @returns {Deferred<T>} The promise and its `resolve`/`reject` functions
79
+ * @example
80
+ * const ready = createDeferred<string>();
81
+ * setTimeout(function () { ready.resolve('open'); }, 10);
82
+ * await ready.promise; // => 'open'
83
+ */
84
+ export declare function createDeferred<T>(): Deferred<T>;
85
+ /**
86
+ * Resolves after `ms` milliseconds. If `options.signal` is aborted (before or during the wait), the timer is cleared and the promise
87
+ * rejects with the signal's `reason` (or an {@link AbortError} if it has none).
88
+ * @param {number} ms - Delay in milliseconds (`0` to `2^31 - 1`)
89
+ * @param {SleepOptions} [options] - Optional abort `signal`
90
+ * @returns {Promise<void>} A promise resolving after the delay
91
+ * @throws {TypeError} (as a rejection) when `ms` is not a number
92
+ * @throws {RangeError} (as a rejection) when `ms` is negative, `NaN` or larger than `2^31 - 1`
93
+ * @example
94
+ * await sleep(10); // resolves after ~10 ms
95
+ * const controller = new AbortController();
96
+ * const nap = sleep(10_000, { signal: controller.signal });
97
+ * controller.abort(); // clears the timer
98
+ * await nap; // throws AbortError
99
+ */
100
+ export declare function sleep(ms: number, options?: SleepOptions): Promise<void>;
101
+ /**
102
+ * Races `promise` against a timer: resolves/rejects like `promise` if it settles within `ms` milliseconds, otherwise rejects with a
103
+ * {@link TimeoutError}. The timer is always cleared. Note that the underlying operation is not cancelled.
104
+ * @template T - The resolved value type
105
+ * @param {PromiseLike<T> | T} promise - The promise (or value) to wait for
106
+ * @param {number} ms - The time limit in milliseconds (`0` to `2^31 - 1`)
107
+ * @param {string} [message] - Message of the `TimeoutError` (defaults to `Operation timed out after <ms> ms`)
108
+ * @returns {Promise<T>} A promise settling like `promise`, or rejecting on timeout
109
+ * @throws {TimeoutError} (as a rejection) when `promise` does not settle within `ms` milliseconds
110
+ * @throws {TypeError} (as a rejection) when `ms` is not a number
111
+ * @throws {RangeError} (as a rejection) when `ms` is negative, `NaN` or larger than `2^31 - 1`
112
+ * @example
113
+ * await withTimeout(Promise.resolve('data'), 5000); // => 'data'
114
+ * await withTimeout(new Promise(function () {}), 10, 'took too long'); // throws TimeoutError
115
+ */
116
+ export declare function withTimeout<T>(promise: PromiseLike<T> | T, ms: number, message?: string): Promise<T>;
117
+ /**
118
+ * Calls `fn` until it succeeds, retrying up to `options.retries` times with exponential backoff:
119
+ * the delay before retry `k` (1-based) is `min(delay * factor^(k - 1), maxDelay)`, optionally randomised with full jitter.
120
+ * Resolves with the first successful result; rejects with the last error once retries are exhausted or `shouldRetry` returns `false`.
121
+ * Every retry waits for at least one timer tick (`setTimeout(0)` for a zero delay), so even `retries: Infinity` with a synchronously
122
+ * throwing `fn` never blocks the thread and stays abortable through `signal`.
123
+ * @template T - The resolved value type
124
+ * @param {(attempt: number) => Promise<T> | T} fn - The operation; receives the 1-based attempt number
125
+ * @param {RetryOptions} [options] - `retries` (3), `delay` (0), `factor` (2), `maxDelay` (Infinity), `jitter` (false), `shouldRetry`, `onRetry`, `signal`
126
+ * @param {RandomGenerator} [random=Math.random] - Random source used for jitter
127
+ * @returns {Promise<T>} The first successful result
128
+ * @throws {TypeError} (as a rejection) when `fn`, `shouldRetry`, `onRetry` or (with `jitter`) `random` is not a function, or a numeric option is not a number
129
+ * @throws {RangeError} (as a rejection) when `retries` is not a non-negative integer or `Infinity`, `delay` is not a finite number >= 0,
130
+ * `factor` is not a finite number > 0, `maxDelay` is negative or `NaN`, or `random()` returns a value outside [0, 1)
131
+ * @throws {unknown} (as a rejection) the last error of `fn`, or the abort reason of `signal`
132
+ * @example
133
+ * let calls = 0;
134
+ * function flaky(): Promise<string> { calls++; return calls < 3 ? Promise.reject(new Error('busy')) : Promise.resolve('ok'); }
135
+ * await retry(flaky, { retries: 5, delay: 10, maxDelay: 2000, jitter: true }); // => 'ok'
136
+ * calls; // => 3
137
+ */
138
+ export declare function retry<T>(fn: (attempt: number) => Promise<T> | T, options?: RetryOptions, random?: RandomGenerator): Promise<T>;
139
+ /**
140
+ * Options accepted by {@link mapWithConcurrency}, {@link mapSettledWithConcurrency} and {@link filterWithConcurrency}.
141
+ */
142
+ export interface ConcurrencyOptions {
143
+ /** Maximum number of callbacks in flight (an integer >= 1, or `Infinity`). Defaults to `Infinity`. */
144
+ concurrency?: number;
145
+ /**
146
+ * Aborting it stops starting new items and rejects straight away with the signal's `reason` (or an {@link AbortError}); callbacks
147
+ * already running are not interrupted (their outcome is ignored), but they receive the signal as their third argument.
148
+ */
149
+ signal?: AbortSignalLike | null;
150
+ /**
151
+ * `true` (the default): reject with the first error and start no further items. `false`: process every item, then reject with an
152
+ * `AggregateError` holding every error (in the order they occurred) if any callback failed.
153
+ */
154
+ stopOnError?: boolean;
155
+ }
156
+ /**
157
+ * A callback run by the `*WithConcurrency` helpers: receives the item, its index and the caller's abort signal.
158
+ * @template T - The item type
159
+ * @template R - The result type
160
+ */
161
+ export type ConcurrentCallback<T, R> = (item: T, index: number, signal: AbortSignalLike | undefined) => PromiseLike<R> | R;
162
+ /**
163
+ * Maps `items` with an async `mapper`, running at most `concurrency` mappers at the same time, and resolves with the results in input
164
+ * order. The third argument is either the concurrency or a {@link ConcurrencyOptions} object:
165
+ * - `stopOnError` (default `true`) rejects with the first error and starts no further items (mappers already running are not
166
+ * cancelled; their outcome is ignored and their rejections are handled). With `false`, every item is processed and the promise then
167
+ * rejects with an `AggregateError` of all the errors if any mapper failed.
168
+ * - `signal` stops starting new items and rejects at once with the signal's `reason`; it is also passed to every mapper as its third
169
+ * argument, so mappers can cancel their own work (e.g. `fetch(url, { signal })`). The abort listener is removed on settle.
170
+ * @template T - The item type
171
+ * @template R - The mapped value type
172
+ * @param {Iterable<T>} items - The items to map (consumed eagerly)
173
+ * @param {ConcurrentCallback<T, R>} mapper - The (possibly async) mapping function, called with `(item, index, signal)`
174
+ * @param {number | ConcurrencyOptions} [options=Infinity] - The maximum number of mappers in flight, or `{ concurrency, signal, stopOnError }`
175
+ * @returns {Promise<R[]>} The mapped values, in input order
176
+ * @throws {TypeError} (as a rejection) when `mapper` is not a function, `concurrency` is not a number, or `signal` is not a signal
177
+ * @throws {RangeError} (as a rejection) when `concurrency` is not an integer >= 1 or `Infinity`
178
+ * @throws {AggregateError} (as a rejection) with `stopOnError: false`, when at least one mapper failed
179
+ * @throws {unknown} (as a rejection) the first error thrown or rejected by `mapper`, or the abort reason of `signal`
180
+ * @example
181
+ * async function size(name: string): Promise<number> { await sleep(5); return name.length; }
182
+ * await mapWithConcurrency(['a', 'bb', 'ccc'], size, 2); // => [1, 2, 3] // in input order, at most 2 running at once
183
+ * @example
184
+ * const controller = new AbortController();
185
+ * async function load(id: number, index: number, signal?: AbortSignalLike): Promise<number> { await sleep(20, { signal }); return id; }
186
+ * const pages = mapWithConcurrency([1, 2, 3], load, { concurrency: 2, signal: controller.signal });
187
+ * controller.abort(new AbortError('navigated away'));
188
+ * await pages; // throws AbortError
189
+ */
190
+ export declare function mapWithConcurrency<T, R>(items: Iterable<T>, mapper: ConcurrentCallback<T, R>, options?: number | ConcurrencyOptions): Promise<R[]>;
191
+ /**
192
+ * Like {@link mapWithConcurrency}, but never rejects because of a mapper: resolves with a `PromiseSettledResult` per item, in input
193
+ * order (like `Promise.allSettled`). It still rejects for invalid arguments, and with the signal's `reason` when `signal` aborts
194
+ * (no new items start; `stopOnError` has no effect).
195
+ * @template T - The item type
196
+ * @template R - The mapped value type
197
+ * @param {Iterable<T>} items - The items to map (consumed eagerly)
198
+ * @param {ConcurrentCallback<T, R>} mapper - The (possibly async) mapping function, called with `(item, index, signal)`
199
+ * @param {number | ConcurrencyOptions} [options=Infinity] - The maximum number of mappers in flight, or `{ concurrency, signal }`
200
+ * @returns {Promise<Array<PromiseSettledResult<Awaited<R>>>>} The outcome of every item, in input order
201
+ * @throws {TypeError} (as a rejection) when `mapper` is not a function, `concurrency` is not a number, or `signal` is not a signal
202
+ * @throws {RangeError} (as a rejection) when `concurrency` is not an integer >= 1 or `Infinity`
203
+ * @throws {unknown} (as a rejection) the abort reason of `signal`
204
+ * @example
205
+ * async function parse(text: string): Promise<number> { const n = Number(text); if (Number.isNaN(n)) throw new Error(`bad: ${text}`); return n; }
206
+ * const results = await mapSettledWithConcurrency(['1', 'x'], parse, 2);
207
+ * results[0]; // => { status: 'fulfilled', value: 1 }
208
+ * results[1]; // => { status: 'rejected', reason: new Error('bad: x') }
209
+ */
210
+ export declare function mapSettledWithConcurrency<T, R>(items: Iterable<T>, mapper: ConcurrentCallback<T, R>, options?: number | ConcurrencyOptions): Promise<Array<PromiseSettledResult<Awaited<R>>>>;
211
+ /**
212
+ * Filters `items` with an async `predicate`, running at most `concurrency` predicates at the same time, and resolves with the items
213
+ * whose predicate returned (or resolved to) a truthy value, in input order. Accepts the same options as {@link mapWithConcurrency}
214
+ * (`concurrency`, `signal`, `stopOnError`), with the same error and abort semantics.
215
+ * @template T - The item type
216
+ * @param {Iterable<T>} items - The items to filter (consumed eagerly)
217
+ * @param {ConcurrentCallback<T, unknown>} predicate - The (possibly async) predicate, called with `(item, index, signal)`
218
+ * @param {number | ConcurrencyOptions} [options=Infinity] - The maximum number of predicates in flight, or `{ concurrency, signal, stopOnError }`
219
+ * @returns {Promise<T[]>} The kept items, in input order
220
+ * @throws {TypeError} (as a rejection) when `predicate` is not a function, `concurrency` is not a number, or `signal` is not a signal
221
+ * @throws {RangeError} (as a rejection) when `concurrency` is not an integer >= 1 or `Infinity`
222
+ * @throws {AggregateError} (as a rejection) with `stopOnError: false`, when at least one predicate failed
223
+ * @throws {unknown} (as a rejection) the first error thrown or rejected by `predicate`, or the abort reason of `signal`
224
+ * @example
225
+ * async function isOnline(host: string): Promise<boolean> { await sleep(5); return host !== 'down.example'; }
226
+ * await filterWithConcurrency(['a.example', 'down.example', 'b.example'], isOnline, { concurrency: 2 }); // => ['a.example', 'b.example']
227
+ */
228
+ export declare function filterWithConcurrency<T, S extends T>(items: Iterable<T>, predicate: (item: T, index: number, signal: AbortSignalLike | undefined) => item is S, options?: number | ConcurrencyOptions): Promise<S[]>;
229
+ /**
230
+ * Filters `items` with an async `predicate`, with bounded concurrency (see the first overload).
231
+ * @template T - The item type
232
+ * @param {Iterable<T>} items - The items to filter (consumed eagerly)
233
+ * @param {ConcurrentCallback<T, unknown>} predicate - The (possibly async) predicate, called with `(item, index, signal)`
234
+ * @param {number | ConcurrencyOptions} [options=Infinity] - The maximum number of predicates in flight, or `{ concurrency, signal, stopOnError }`
235
+ * @returns {Promise<T[]>} The kept items, in input order
236
+ * @example
237
+ * await filterWithConcurrency([1, 2, 3, 4], async function (n) { return n % 2 === 0; }); // => [2, 4]
238
+ */
239
+ export declare function filterWithConcurrency<T>(items: Iterable<T>, predicate: ConcurrentCallback<T, unknown>, options?: number | ConcurrencyOptions): Promise<T[]>;
240
+ /**
241
+ * Awaits a promise (or calls a possibly async function and awaits its result) and captures the outcome as a {@link Result} tuple.
242
+ * The returned promise never rejects: synchronous throws and rejections both become `[error, undefined]`.
243
+ * @template T - The resolved value type
244
+ * @param {PromiseLike<T> | (() => PromiseLike<T> | T)} fnOrPromise - A promise, or a function to call (with no arguments)
245
+ * @returns {Promise<Result<T>>} `[undefined, value]` on success, `[error, undefined]` on failure
246
+ * @example
247
+ * await attemptAsync(Promise.resolve(42)); // => [undefined, 42]
248
+ * const [error, value] = await attemptAsync(function () { return JSON.parse('{'); });
249
+ * error instanceof SyntaxError; // => true
250
+ * value; // => undefined
251
+ */
252
+ export declare function attemptAsync<T>(fnOrPromise: PromiseLike<T> | (() => PromiseLike<T> | T)): Promise<Result<T>>;
253
+ /**
254
+ * Options accepted by {@link createLimiter}.
255
+ */
256
+ export interface LimiterOptions {
257
+ /** When `true`, {@link Limiter.clearQueue} rejects the promises of the discarded tasks with an {@link AbortError}. Defaults to `false` (they never settle). */
258
+ rejectOnClear?: boolean;
259
+ /**
260
+ * Largest number of tasks allowed to wait for a slot (an integer >= 0, or `Infinity`). Once that many wait, further calls reject
261
+ * with a `RangeError` straight away, without queueing or running their task. Set it whenever tasks are created from untrusted or
262
+ * unbounded input (e.g. one per incoming request): an unbounded queue grows until the process runs out of memory.
263
+ * @default Infinity
264
+ */
265
+ maxPending?: number;
266
+ }
267
+ /**
268
+ * A concurrency limiter as returned by {@link createLimiter}.
269
+ */
270
+ export interface Limiter {
271
+ /**
272
+ * Runs `fn(...args)` as soon as fewer than `concurrency` tasks are active (immediately and synchronously when a slot is free),
273
+ * and settles like its result. Synchronous throws become rejections.
274
+ * @throws {TypeError} (as a rejection) when `fn` is not a function
275
+ * @throws {RangeError} (as a rejection) when no slot is free and `maxPending` tasks are already waiting
276
+ */
277
+ <A extends unknown[], T>(fn: (...args: A) => PromiseLike<T> | T, ...args: A): Promise<T>;
278
+ /** Number of tasks currently running. */
279
+ readonly activeCount: number;
280
+ /** Number of tasks waiting for a free slot. */
281
+ readonly pendingCount: number;
282
+ /** Discards the waiting tasks (running tasks are not affected). */
283
+ clearQueue(): void;
284
+ }
285
+ /**
286
+ * Creates a limiter that runs at most `concurrency` tasks at the same time, starting waiting tasks in FIFO order (like `p-limit`).
287
+ * The queue of waiting tasks is unbounded by default: pass `maxPending` to bound it (calls beyond it reject with a `RangeError`)
288
+ * whenever the number of calls is not under your control.
289
+ * @param {number} concurrency - Maximum number of tasks running at once (an integer >= 1, or `Infinity`)
290
+ * @param {LimiterOptions} [options] - `rejectOnClear` (default `false`) and `maxPending` (default `Infinity`)
291
+ * @returns {Limiter} The `limit(fn, ...args)` function, with `activeCount`, `pendingCount` and `clearQueue()`
292
+ * @throws {TypeError} when `concurrency` or `maxPending` is not a number
293
+ * @throws {RangeError} when `concurrency` is not an integer >= 1 or `Infinity`, or `maxPending` is not an integer >= 0 or `Infinity`
294
+ * @example
295
+ * const limit = createLimiter(2);
296
+ * async function double(n: number): Promise<number> { await sleep(5); return n * 2; }
297
+ * const results = Promise.all([1, 2, 3].map(function (n) { return limit(double, n); }));
298
+ * limit.activeCount; // => 2
299
+ * limit.pendingCount; // => 1
300
+ * await results; // => [2, 4, 6]
301
+ * @example
302
+ * const limit = createLimiter(1, { maxPending: 1 });
303
+ * const running = limit(sleep, 5);
304
+ * const queued = limit(sleep, 5);
305
+ * await limit(sleep, 5); // throws RangeError // the queue is full
306
+ * await Promise.all([running, queued]);
307
+ */
308
+ export declare function createLimiter(concurrency: number, options?: LimiterOptions): Limiter;
309
+ /**
310
+ * Options accepted by {@link createQueue}.
311
+ */
312
+ export interface QueueOptions {
313
+ /** Maximum number of tasks running at once (an integer >= 1, or `Infinity`). Defaults to `Infinity`. */
314
+ concurrency?: number;
315
+ /**
316
+ * Aborting it removes every waiting task and rejects its promise with the signal's `reason` (or an {@link AbortError}), and so does
317
+ * every later `add`. Running tasks are not interrupted: they receive the signal and settle on their own.
318
+ */
319
+ signal?: AbortSignalLike | null;
320
+ }
321
+ /**
322
+ * Options accepted by {@link Queue.add}.
323
+ */
324
+ export interface QueueAddOptions {
325
+ /** Tasks with a higher priority start first; tasks of equal priority start in the order they were added. Defaults to `0`. */
326
+ priority?: number;
327
+ /**
328
+ * Aborting it before the task starts removes the task from the queue (it never runs) and rejects its promise with the signal's
329
+ * `reason`. Once started, the task receives it (combined with the queue's signal, when both are set).
330
+ */
331
+ signal?: AbortSignalLike | null;
332
+ }
333
+ /**
334
+ * A priority task queue as returned by {@link createQueue}.
335
+ */
336
+ export interface Queue {
337
+ /**
338
+ * Adds a task and returns a promise that settles like it. The task is called with an abort signal (see {@link QueueAddOptions.signal})
339
+ * when it starts: immediately and synchronously if a slot is free, nothing is waiting and the queue is not paused. Synchronous throws
340
+ * become rejections.
341
+ * @throws {TypeError} (as a rejection) when `task` is not a function, `priority` is not a number, or `signal` is not a signal
342
+ * @throws {RangeError} (as a rejection) when `priority` is `NaN`
343
+ */
344
+ add<T>(task: (signal: AbortSignalLike | undefined) => PromiseLike<T> | T, options?: QueueAddOptions): Promise<T>;
345
+ /** Number of tasks waiting to start. */
346
+ readonly size: number;
347
+ /** Number of tasks running. */
348
+ readonly pending: number;
349
+ /** Whether the queue is paused. */
350
+ readonly isPaused: boolean;
351
+ /** Stops starting tasks (running tasks continue) until `resume()` is called. */
352
+ pause(): void;
353
+ /** Starts waiting tasks again, up to the concurrency. */
354
+ resume(): void;
355
+ /** Removes every waiting task, rejecting its promise with an {@link AbortError} (running tasks are not affected). */
356
+ clear(): void;
357
+ /** Resolves as soon as no task is waiting (immediately if none is). Each call returns a new promise, so it can be awaited again later. */
358
+ onEmpty(): Promise<void>;
359
+ /** Resolves as soon as no task is waiting or running (immediately if none is). Each call returns a new promise. */
360
+ onIdle(): Promise<void>;
361
+ }
362
+ /**
363
+ * Creates a task queue that runs at most `concurrency` tasks at the same time, starting the waiting task with the highest `priority`
364
+ * first and tasks of equal priority in FIFO order (a stable binary heap, so `add` and every start are O(log n)). It has no timers.
365
+ *
366
+ * Cancellation is precise: a task whose own `signal` aborts while it waits is removed from the queue (it never runs) and its promise
367
+ * rejects with the signal's `reason`; aborting the queue's `signal` does the same for every waiting task and rejects every later `add`.
368
+ * Running tasks are never interrupted, but they receive the signal(s) to cancel their own work. Listeners are removed as soon as a task
369
+ * starts or leaves the queue.
370
+ * @param {QueueOptions} [options] - `concurrency` (default `Infinity`) and `signal`
371
+ * @returns {Queue} The queue
372
+ * @throws {TypeError} when `concurrency` is not a number or `signal` is not a signal
373
+ * @throws {RangeError} when `concurrency` is not an integer >= 1 or `Infinity`
374
+ * @example
375
+ * const queue = createQueue({ concurrency: 1 });
376
+ * const order: string[] = [];
377
+ * async function job(name: string): Promise<string> { await sleep(5); order.push(name); return name; }
378
+ * queue.add(function () { return job('first'); }); // starts at once
379
+ * queue.add(function () { return job('low'); });
380
+ * queue.add(function () { return job('urgent'); }, { priority: 10 });
381
+ * queue.size; // => 2
382
+ * queue.pending; // => 1
383
+ * await queue.onIdle();
384
+ * order; // => ['first', 'urgent', 'low']
385
+ * @example
386
+ * const queue = createQueue({ concurrency: 1 });
387
+ * const controller = new AbortController();
388
+ * queue.add(function () { return sleep(10); });
389
+ * const waiting = queue.add(function () { return 'never runs'; }, { signal: controller.signal });
390
+ * controller.abort(new AbortError('not needed any more'));
391
+ * await waiting; // throws AbortError
392
+ * queue.size; // => 0
393
+ */
394
+ export declare function createQueue(options?: QueueOptions): Queue;
395
+ /**
396
+ * Options accepted by {@link createRateLimiter}.
397
+ */
398
+ export interface RateLimiterOptions {
399
+ /** Maximum number of calls that may start within any window of `interval` milliseconds (an integer >= 1). */
400
+ limit: number;
401
+ /** Length of the sliding window in milliseconds (`0` to `2^31 - 1`). */
402
+ interval: number;
403
+ /**
404
+ * Aborting it rejects every waiting call (and every later one) with the signal's `reason` (or an {@link AbortError}) and clears the
405
+ * timer. Calls already started are not affected.
406
+ */
407
+ signal?: AbortSignalLike | null;
408
+ }
409
+ /**
410
+ * A rate limiter as returned by {@link createRateLimiter}.
411
+ */
412
+ export interface RateLimiter {
413
+ /**
414
+ * Calls `fn(...args)` as soon as the rate limit allows it (immediately and synchronously when it does and no call is waiting), and
415
+ * settles like its result. Calls start in FIFO order and are never dropped. Synchronous throws become rejections.
416
+ * @throws {TypeError} (as a rejection) when `fn` is not a function
417
+ */
418
+ schedule<A extends unknown[], T>(fn: (...args: A) => PromiseLike<T> | T, ...args: A): Promise<T>;
419
+ /**
420
+ * Returns a rate-limited version of `fn`: every call goes through {@link RateLimiter.schedule} (with `this` forwarded) and returns a promise.
421
+ * @throws {TypeError} when `fn` is not a function
422
+ */
423
+ wrap<A extends unknown[], T, This = unknown>(fn: (this: This, ...args: A) => PromiseLike<T> | T): (this: This, ...args: A) => Promise<Awaited<T>>;
424
+ /** Number of calls waiting for the rate limit. */
425
+ readonly pendingCount: number;
426
+ /** Removes every waiting call, rejecting its promise with an {@link AbortError}, and clears the timer. */
427
+ clearQueue(): void;
428
+ }
429
+ /**
430
+ * Creates a rate limiter that starts at most `limit` calls within any window of `interval` milliseconds. Calls beyond the limit are
431
+ * queued (never dropped, unlike `throttle`) and start in FIFO order as soon as the window allows.
432
+ *
433
+ * The window slides (it is "strict"): a call may start only once the call `limit` starts before it started at least `interval` ms ago.
434
+ * Fixed windows, the default of several libraries, let `2 × limit` calls through around a window boundary. Only the start times of the
435
+ * last `limit` calls are kept, and at most one timer exists, only while calls are waiting: an idle limiter holds no timer, so it never
436
+ * keeps a process alive. `limit` caps how often calls start, not how many run at once (combine with {@link createLimiter} for that).
437
+ * @param {RateLimiterOptions} options - `limit`, `interval` and an optional `signal`
438
+ * @returns {RateLimiter} The limiter, with `schedule`, `wrap`, `pendingCount` and `clearQueue`
439
+ * @throws {TypeError} when `options` is not an object, `limit` or `interval` is not a number, or `signal` is not a signal
440
+ * @throws {RangeError} when `limit` is not an integer >= 1, or `interval` is not between `0` and `2^31 - 1`
441
+ * @example
442
+ * const limiter = createRateLimiter({ limit: 2, interval: 50 });
443
+ * const started: number[] = [];
444
+ * const begin = Date.now();
445
+ * function call(id: number): number { started.push(Date.now() - begin); return id; }
446
+ * await Promise.all([1, 2, 3].map(function (id) { return limiter.schedule(call, id); })); // => [1, 2, 3]
447
+ * started[1] < 50; // => true // the first two start at once
448
+ * started[2] >= 49; // => true // the third waits for the window to slide
449
+ * @example
450
+ * // doctest: skip
451
+ * const search = createRateLimiter({ limit: 5, interval: 1000 }).wrap(function (query: string) { return fetch(`/api?q=${query}`); });
452
+ */
453
+ export declare function createRateLimiter(options: RateLimiterOptions): RateLimiter;
454
+ /**
455
+ * Values considered falsy by JavaScript, removed from a type by {@link Truthy}.
456
+ */
457
+ type Falsy = false | 0 | 0n | '' | null | undefined;
458
+ /**
459
+ * `T` without its falsy members (`false`, `0`, `0n`, `''`, `null`, `undefined`).
460
+ * @template T - The type to narrow
461
+ * @example
462
+ * type T = Truthy<string | null>; // string
463
+ */
464
+ export type Truthy<T> = Exclude<T, Falsy>;
465
+ /**
466
+ * Options accepted by {@link pollUntil}.
467
+ */
468
+ export interface PollOptions {
469
+ /** Delay in ms between the end of one check and the start of the next. Defaults to `100`. */
470
+ interval?: number;
471
+ /** Overall time limit in ms, after which the promise rejects with a {@link TimeoutError}. Defaults to `Infinity`. */
472
+ timeout?: number;
473
+ /** Stops polling, rejecting with the signal's `reason` (or an {@link AbortError}). */
474
+ signal?: AbortSignalLike;
475
+ }
476
+ /**
477
+ * Calls `check` immediately and then every `interval` ms (waiting for async checks to settle in between, so checks never overlap)
478
+ * until it returns (or resolves to) a truthy value, and resolves with that value. All timers and listeners are cleaned up on settle.
479
+ * @template T - The value produced by `check`
480
+ * @param {() => T | PromiseLike<T>} check - The condition to poll
481
+ * @param {PollOptions} [options] - `interval` (100), `timeout` (Infinity) and `signal`
482
+ * @returns {Promise<Truthy<Awaited<T>>>} The first truthy value
483
+ * @throws {TimeoutError} (as a rejection) when no truthy value was produced within `timeout` ms
484
+ * @throws {RangeError} (as a rejection) when `interval` is not a number between `0` and `2^31 - 1`, or `timeout` is neither such a number nor `Infinity`
485
+ * @throws {TypeError} (as a rejection) when `check` is not a function, or `interval` or `timeout` is not a number
486
+ * @throws {unknown} (as a rejection) the error thrown or rejected by `check`, or the abort reason of `signal`
487
+ * @example
488
+ * let status = 'loading';
489
+ * setTimeout(function () { status = 'ready'; }, 30);
490
+ * await pollUntil(function () { return status === 'ready' && status; }, { interval: 10, timeout: 5000 }); // => 'ready'
491
+ * await pollUntil(function () { return false; }, { interval: 10, timeout: 50 }); // throws TimeoutError
492
+ */
493
+ export declare function pollUntil<T>(check: () => T | PromiseLike<T>, options?: PollOptions): Promise<Truthy<Awaited<T>>>;
494
+ /**
495
+ * Like `Promise.all`, but for an object of promises (or values): resolves with an object with the same keys and the awaited values.
496
+ * Rejects with the first rejection. Own enumerable string and symbol keys are used; the input is not mutated.
497
+ * @template T - The input object type
498
+ * @param {T} obj - An object whose values are promises or plain values
499
+ * @returns {Promise<{ [K in keyof T]: Awaited<T[K]> }>} The awaited values, keyed like `obj`
500
+ * @throws {TypeError} (as a rejection) when `obj` is not a non-array object
501
+ * @example
502
+ * await promiseAllObject({ user: Promise.resolve('Ada'), posts: sleep(5).then(function () { return [1, 2]; }) }); // => { user: 'Ada', posts: [1, 2] }
503
+ */
504
+ export declare function promiseAllObject<T extends object>(obj: T): Promise<{
505
+ -readonly [K in keyof T]: Awaited<T[K]>;
506
+ }>;
507
+ /**
508
+ * Like `Promise.allSettled`, but for an object of promises (or values): resolves with an object with the same keys and a
509
+ * `PromiseSettledResult` for each value. Never rejects (except for invalid input). Own enumerable string and symbol keys are used.
510
+ * @template T - The input object type
511
+ * @param {T} obj - An object whose values are promises or plain values
512
+ * @returns {Promise<{ [K in keyof T]: PromiseSettledResult<Awaited<T[K]>> }>} The settled results, keyed like `obj`
513
+ * @throws {TypeError} (as a rejection) when `obj` is not a non-array object
514
+ * @example
515
+ * const results = await promiseAllSettledObject({ a: Promise.resolve(1), b: Promise.reject(new Error('x')) });
516
+ * results.a; // => { status: 'fulfilled', value: 1 }
517
+ * results.b; // => { status: 'rejected', reason: Error('x') }
518
+ */
519
+ export declare function promiseAllSettledObject<T extends object>(obj: T): Promise<{
520
+ -readonly [K in keyof T]: PromiseSettledResult<Awaited<T[K]>>;
521
+ }>;
522
+ /**
523
+ * A debounced async function as returned by {@link debounceAsync}.
524
+ * @template F - The original function type
525
+ */
526
+ export interface DebouncedAsync<F extends (...args: never[]) => unknown> {
527
+ (this: ThisParameterType<F>, ...args: Parameters<F>): Promise<Awaited<ReturnType<F>>>;
528
+ /** Cancels the pending invocation; the promises of the current burst reject with an {@link AbortError}. */
529
+ cancel(): void;
530
+ /** Performs the pending invocation now and returns its shared promise (`undefined` when nothing is pending). */
531
+ flush(): Promise<Awaited<ReturnType<F>>> | undefined;
532
+ }
533
+ /**
534
+ * Creates a debounced version of a (possibly async) function: `fn` is invoked `wait` ms after the last call of a burst, with the latest
535
+ * `this` and arguments, and every call of the burst returns a promise that settles with the result of that single invocation.
536
+ * Calls made while an invocation is running start a new burst.
537
+ * @template F - The type of the function to debounce
538
+ * @param {F} fn - The function to debounce
539
+ * @param {number} wait - The quiet period in milliseconds (`0` to `2^31 - 1`)
540
+ * @returns {DebouncedAsync<F>} The debounced function, with `.cancel()` and `.flush()`
541
+ * @throws {TypeError} when `fn` is not a function, or `wait` is not a number
542
+ * @throws {RangeError} when `wait` is negative, `NaN` or larger than `2^31 - 1`
543
+ * @example
544
+ * const queries: string[] = [];
545
+ * const search = debounceAsync(async function (query: string) { queries.push(query); return `results for ${query}`; }, 20);
546
+ * const first = search('a');
547
+ * const second = search('ab');
548
+ * await Promise.all([first, second]); // => ['results for ab', 'results for ab']
549
+ * queries; // => ['ab'] // one call for the whole burst
550
+ */
551
+ export declare function debounceAsync<F extends (...args: never[]) => unknown>(fn: F, wait: number): DebouncedAsync<F>;
552
+ /**
553
+ * Options accepted by {@link memoizeAsync}.
554
+ * @template F - The memoized function type
555
+ */
556
+ export interface MemoizeAsyncOptions<F extends AnyFunction> {
557
+ /** Computes the cache key from the call arguments (`this` is forwarded). Defaults to `defaultMemoizeKey` (from the functions module). */
558
+ resolver?: (this: ThisParameterType<F>, ...args: Parameters<F>) => unknown;
559
+ /**
560
+ * Where resolved values are stored. Defaults to a new `Map`, or, with `ttl`, to an unbounded `createLRUCache` (from the cache module).
561
+ * Pass `createLRUCache({ max })` to bound it. With `ttl`, the cache's `set` is called with `{ ttl }` as its third argument.
562
+ */
563
+ cache?: MemoizeCache<unknown, Awaited<ReturnType<F>>>;
564
+ /** Time-to-live of every resolved value in milliseconds (`> 0`, or `Infinity`). Defaults to no expiry. */
565
+ ttl?: number;
566
+ }
567
+ /**
568
+ * An async function memoized with {@link memoizeAsync}.
569
+ * @template F - The original function type
570
+ */
571
+ export interface MemoizedAsync<F extends AnyFunction> {
572
+ (this: ThisParameterType<F>, ...args: Parameters<F>): Promise<Awaited<ReturnType<F>>>;
573
+ /** The cache of resolved values, keyed by the resolver's result. */
574
+ readonly cache: MemoizeCache<unknown, Awaited<ReturnType<F>>>;
575
+ /** Forgets every resolved value and every call in flight (a call in flight still settles its callers, but its value is not cached). */
576
+ clear(): void;
577
+ /** Forgets the resolved value and the call in flight for these arguments; returns whether there was one. */
578
+ delete(...args: Parameters<F>): boolean;
579
+ /**
580
+ * Calls the memoized function (with `this` undefined) but stops waiting when `signal` aborts: this caller's promise rejects with the
581
+ * signal's `reason`, while the shared call keeps running for the other callers and still fills the cache. An already-aborted signal
582
+ * rejects without calling anything.
583
+ */
584
+ withSignal(signal: AbortSignalLike | null | undefined, ...args: Parameters<F>): Promise<Awaited<ReturnType<F>>>;
585
+ }
586
+ /**
587
+ * Memoizes an async (or promise-returning) function, correctly:
588
+ * - Single flight: concurrent calls with the same key share one in-flight call instead of starting one each.
589
+ * - Only resolved values are cached. A rejection (or a synchronous throw) is passed to the callers of that call and then forgotten, so
590
+ * the next call retries; `memoize` or `once` on an async function would cache the rejected promise forever.
591
+ * - `ttl` expires resolved values; `cache` can be any `Map`-like store, such as `createLRUCache` to bound memory.
592
+ * - `withSignal(signal, ...args)` lets one caller stop waiting without cancelling the work shared with the others.
593
+ * - `clear()` / `delete(...args)` invalidate: a call in flight at that moment does not write its (possibly stale) value to the cache.
594
+ * @template F - The type of the function to memoize
595
+ * @param {F} fn - The function to memoize
596
+ * @param {MemoizeAsyncOptions<F>} [options] - `resolver` (key function), `cache` and `ttl`
597
+ * @returns {MemoizedAsync<F>} The memoized function, with `cache`, `clear()`, `delete(...args)` and `withSignal(signal, ...args)`
598
+ * @throws {TypeError} when `fn` or `resolver` is not a function, or `ttl` is not a number
599
+ * @throws {RangeError} when `ttl` is not a number > 0
600
+ * @example
601
+ * let requests = 0;
602
+ * async function fetchUser(id: number): Promise<{ id: number }> { requests++; await sleep(5); return { id }; }
603
+ * const getUser = memoizeAsync(fetchUser, { ttl: 60_000 });
604
+ * const [a, b] = await Promise.all([getUser(1), getUser(1)]);
605
+ * a === b; // => true
606
+ * await getUser(1); // => { id: 1 } // cached
607
+ * requests; // => 1
608
+ * @example
609
+ * let attempts = 0;
610
+ * const flaky = memoizeAsync(async function (): Promise<string> { attempts++; if (attempts === 1) throw new Error('offline'); return 'ok'; });
611
+ * await flaky(); // throws Error
612
+ * await flaky(); // => 'ok' // the rejection was not cached
613
+ */
614
+ export declare function memoizeAsync<F extends AnyFunction>(fn: F, options?: MemoizeAsyncOptions<F>): MemoizedAsync<F>;
615
+ /**
616
+ * Runs (possibly async) tasks one at a time, in iteration order, and resolves with their results in the same order. Each task is
617
+ * only pulled from the iterable (and started) after the previous one has settled, so lazy iterables and generators are supported.
618
+ * Rejects with the first error, without starting the remaining tasks.
619
+ * @template T - The task result type
620
+ * @param {Iterable<() => PromiseLike<T> | T>} tasks - The tasks to run
621
+ * @returns {Promise<T[]>} The results, in order
622
+ * @throws {TypeError} (as a rejection) when a task is not a function
623
+ * @throws {unknown} (as a rejection) the first error thrown or rejected by a task
624
+ * @example
625
+ * const log: string[] = [];
626
+ * async function migrate(version: number): Promise<number> { await sleep(10 - version); log.push(`v${version}`); return version; }
627
+ * await sequence([function () { return migrate(1); }, function () { return migrate(2); }]); // => [1, 2]
628
+ * log; // => ['v1', 'v2'] // each task starts after the previous one settled
629
+ */
630
+ export declare function sequence<T>(tasks: Iterable<() => PromiseLike<T> | T>): Promise<T[]>;
631
+ /**
632
+ * The platform's `AbortSignal` type when the consumer's TypeScript environment declares one (DOM or Node typings), and
633
+ * {@link AbortSignalLike} otherwise. {@link timeoutSignal} and {@link anySignal} return real `AbortSignal`s created by the platform's
634
+ * `AbortController`, so their results can be passed straight to `fetch`, `addEventListener` and other platform APIs.
635
+ */
636
+ export type PlatformAbortSignal = typeof globalThis extends {
637
+ AbortSignal: {
638
+ prototype: infer S;
639
+ };
640
+ } ? S : AbortSignalLike;
641
+ /**
642
+ * Creates an `AbortSignal` that aborts with a {@link TimeoutError} after `ms` milliseconds — like the platform's `AbortSignal.timeout`,
643
+ * but with this library's `TimeoutError` as the reason (so `error instanceof TimeoutError` works across the async helpers).
644
+ *
645
+ * The timer cannot be cancelled and is not `unref`'d (browsers have no such concept): in Node it keeps the process alive until it
646
+ * fires, so prefer short timeouts or an `AbortController` you abort yourself for long-lived work. `Infinity` gives a signal that never
647
+ * aborts (and starts no timer), which is handy for optional timeouts.
648
+ * @param {number} ms - Delay in milliseconds (`0` to `2^31 - 1`, or `Infinity`)
649
+ * @returns {PlatformAbortSignal} A new signal that aborts after `ms` milliseconds
650
+ * @throws {TypeError} when `ms` is not a number
651
+ * @throws {RangeError} when `ms` is negative, `NaN` or larger than `2^31 - 1` (and not `Infinity`)
652
+ * @throws {Error} when the environment has no `AbortController`
653
+ * @example
654
+ * const signal = timeoutSignal(10);
655
+ * signal.aborted; // => false
656
+ * await sleep(30);
657
+ * signal.aborted; // => true
658
+ * signal.reason instanceof TimeoutError; // => true
659
+ * signal.reason.message; // => 'timeoutSignal: timed out after 10 ms'
660
+ * @example
661
+ * // doctest: skip
662
+ * const response = await fetch(url, { signal: timeoutSignal(5000) });
663
+ */
664
+ export declare function timeoutSignal(ms: number): PlatformAbortSignal;
665
+ /**
666
+ * Combines abort signals: returns a new `AbortSignal` that aborts as soon as any of the inputs aborts, with that input's `reason`
667
+ * (or an {@link AbortError} when it has none) — like the platform's `AbortSignal.any`, but accepting any {@link AbortSignalLike}.
668
+ * `null` and `undefined` entries are ignored, so optional signals can be passed directly; with no signals the result never aborts.
669
+ *
670
+ * If an input is already aborted, the result is returned already aborted (with the reason of the first such input) and no listener
671
+ * is attached. Otherwise one `abort` listener is added to each input, and all of them are removed as soon as the result aborts.
672
+ * Note that if no input ever aborts, those listeners stay attached for as long as the inputs live (unlike the native implementation,
673
+ * which holds them weakly), so avoid creating unbounded numbers of combined signals from one long-lived signal.
674
+ * @param {Iterable<AbortSignalLike | null | undefined>} signals - The signals to combine (consumed eagerly)
675
+ * @returns {PlatformAbortSignal} A new signal
676
+ * @throws {TypeError} when `signals` is not iterable, or one of its entries is not a signal, `null` or `undefined`
677
+ * @throws {Error} when the environment has no `AbortController`
678
+ * @example
679
+ * const user = new AbortController();
680
+ * const shutdown = new AbortController();
681
+ * const signal = anySignal([user.signal, shutdown.signal, undefined]);
682
+ * signal.aborted; // => false
683
+ * shutdown.abort('shutting down');
684
+ * signal.aborted; // => true
685
+ * signal.reason; // => 'shutting down'
686
+ * @example
687
+ * // doctest: skip
688
+ * await fetch(url, { signal: anySignal([options.signal, timeoutSignal(5000)]) });
689
+ */
690
+ export declare function anySignal(signals: Iterable<AbortSignalLike | null | undefined>): PlatformAbortSignal;
691
+ /**
692
+ * Settles like `promise`, unless `signal` aborts first, in which case it rejects with the signal's `reason` (or an
693
+ * {@link AbortError} when it has none). An already-aborted signal rejects immediately. The abort listener is removed as soon as
694
+ * `promise` settles. `signal` may be `null` or `undefined`, in which case this simply settles like `promise`.
695
+ *
696
+ * This only stops *waiting*: the underlying operation is not cancelled and keeps running (pass the signal to the operation itself,
697
+ * e.g. to `fetch`, when it supports cancellation). A later rejection of `promise` is handled, so it does not surface as an
698
+ * unhandled rejection.
699
+ * @template T - The resolved value type
700
+ * @param {PromiseLike<T> | T} promise - The promise (or value) to wait for
701
+ * @param {AbortSignalLike | null | undefined} signal - The signal that stops the wait
702
+ * @returns {Promise<T>} A promise settling like `promise`, or rejecting when `signal` aborts first
703
+ * @throws {TypeError} (as a rejection) when `signal` is not a signal, `null` or `undefined`
704
+ * @throws {unknown} (as a rejection) the abort reason of `signal`, or the rejection of `promise`
705
+ * @example
706
+ * const controller = new AbortController();
707
+ * await abortable(Promise.resolve(42), controller.signal); // => 42
708
+ * const pending = abortable(new Promise(function () {}), controller.signal);
709
+ * controller.abort(new AbortError('stopped waiting'));
710
+ * await pending; // throws AbortError
711
+ * await abortable(Promise.resolve(42), controller.signal); // throws AbortError
712
+ * await abortable(Promise.resolve(42), undefined); // => 42
713
+ */
714
+ export declare function abortable<T>(promise: PromiseLike<T> | T, signal: AbortSignalLike | null | undefined): Promise<T>;
715
+ /**
716
+ * Throws the signal's `reason` (or an {@link AbortError} when it has none) if `signal` is aborted; does nothing otherwise. Works with
717
+ * any {@link AbortSignalLike} (unlike the platform's `signal.throwIfAborted()`), and accepts `null` / `undefined` for optional signals.
718
+ * @param {AbortSignalLike | null | undefined} signal - The signal to check
719
+ * @returns {void}
720
+ * @throws {unknown} the abort reason of `signal`, when it is aborted
721
+ * @throws {TypeError} when `signal` is not a signal, `null` or `undefined`
722
+ * @example
723
+ * const controller = new AbortController();
724
+ * throwIfAborted(controller.signal); // => undefined
725
+ * throwIfAborted(undefined); // => undefined
726
+ * controller.abort(new TimeoutError());
727
+ * throwIfAborted(controller.signal); // throws TimeoutError
728
+ */
729
+ export declare function throwIfAborted(signal: AbortSignalLike | null | undefined): void;