@vielzeug/toolkit 1.0.14 → 1.1.3

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 (71) hide show
  1. package/README.md +546 -0
  2. package/dist/async/attempt.cjs.map +1 -0
  3. package/dist/async/attempt.js.map +1 -0
  4. package/dist/async/defer.cjs +2 -0
  5. package/dist/async/defer.cjs.map +1 -0
  6. package/dist/async/defer.js +10 -0
  7. package/dist/async/defer.js.map +1 -0
  8. package/dist/async/delay.cjs.map +1 -0
  9. package/dist/async/delay.js.map +1 -0
  10. package/dist/async/parallel.cjs.map +1 -0
  11. package/dist/async/parallel.js.map +1 -0
  12. package/dist/async/pool.cjs +2 -0
  13. package/dist/async/pool.cjs.map +1 -0
  14. package/dist/async/pool.js +22 -0
  15. package/dist/async/pool.js.map +1 -0
  16. package/dist/async/predict.cjs.map +1 -0
  17. package/dist/async/predict.js.map +1 -0
  18. package/dist/async/queue.cjs +2 -0
  19. package/dist/async/queue.cjs.map +1 -0
  20. package/dist/async/queue.js +57 -0
  21. package/dist/async/queue.js.map +1 -0
  22. package/dist/async/race.cjs +2 -0
  23. package/dist/async/race.cjs.map +1 -0
  24. package/dist/async/race.js +8 -0
  25. package/dist/async/race.js.map +1 -0
  26. package/dist/async/retry.cjs.map +1 -0
  27. package/dist/{function → async}/retry.js +4 -4
  28. package/dist/async/retry.js.map +1 -0
  29. package/dist/async/sleep.cjs +2 -0
  30. package/dist/async/sleep.cjs.map +1 -0
  31. package/dist/{function → async}/sleep.js +1 -1
  32. package/dist/async/sleep.js.map +1 -0
  33. package/dist/async/waitFor.cjs +2 -0
  34. package/dist/async/waitFor.cjs.map +1 -0
  35. package/dist/async/waitFor.js +37 -0
  36. package/dist/async/waitFor.js.map +1 -0
  37. package/dist/index.cjs +1 -1
  38. package/dist/index.d.ts +175 -0
  39. package/dist/index.js +242 -230
  40. package/dist/index.js.map +1 -1
  41. package/dist/logit/dist/logit.cjs +1 -1
  42. package/dist/logit/dist/logit.cjs.map +1 -1
  43. package/dist/logit/dist/logit.js +147 -64
  44. package/dist/logit/dist/logit.js.map +1 -1
  45. package/dist/object/cache.cjs +2 -0
  46. package/dist/object/cache.cjs.map +1 -0
  47. package/dist/object/cache.js +63 -0
  48. package/dist/object/cache.js.map +1 -0
  49. package/package.json +1 -1
  50. package/dist/function/attempt.cjs.map +0 -1
  51. package/dist/function/attempt.js.map +0 -1
  52. package/dist/function/delay.cjs.map +0 -1
  53. package/dist/function/delay.js.map +0 -1
  54. package/dist/function/parallel.cjs.map +0 -1
  55. package/dist/function/parallel.js.map +0 -1
  56. package/dist/function/predict.cjs.map +0 -1
  57. package/dist/function/predict.js.map +0 -1
  58. package/dist/function/retry.cjs.map +0 -1
  59. package/dist/function/retry.js.map +0 -1
  60. package/dist/function/sleep.cjs +0 -2
  61. package/dist/function/sleep.cjs.map +0 -1
  62. package/dist/function/sleep.js.map +0 -1
  63. /package/dist/{function → async}/attempt.cjs +0 -0
  64. /package/dist/{function → async}/attempt.js +0 -0
  65. /package/dist/{function → async}/delay.cjs +0 -0
  66. /package/dist/{function → async}/delay.js +0 -0
  67. /package/dist/{function → async}/parallel.cjs +0 -0
  68. /package/dist/{function → async}/parallel.js +0 -0
  69. /package/dist/{function → async}/predict.cjs +0 -0
  70. /package/dist/{function → async}/predict.js +0 -0
  71. /package/dist/{function → async}/retry.cjs +0 -0
package/README.md ADDED
@@ -0,0 +1,546 @@
1
+ # @vielzeug/toolkit
2
+
3
+ <div align="center">
4
+ <img src="../../docs/public/logo-utils.svg" alt="Toolkit Logo" width="120" />
5
+
6
+ <p><strong>A comprehensive, type-safe utility library for modern JavaScript and TypeScript.</strong></p>
7
+
8
+ [![npm version](https://img.shields.io/npm/v/@vielzeug/toolkit.svg)](https://www.npmjs.com/package/@vielzeug/toolkit)
9
+ [![npm downloads](https://img.shields.io/npm/dm/@vielzeug/toolkit.svg)](https://www.npmjs.com/package/@vielzeug/toolkit)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
11
+ [![TypeScript](https://img.shields.io/badge/TypeScript-100%25-blue)](https://www.typescriptlang.org/)
12
+ [![Bundle Size](https://img.shields.io/bundlephobia/minzip/@vielzeug/toolkit)](https://bundlephobia.com/package/@vielzeug/toolkit)
13
+
14
+ </div>
15
+
16
+ ## Features
17
+
18
+ - 🎯 **119 Type-Safe Utilities** - Covering arrays, objects, strings, async operations, and more
19
+ - 📦 **Tree-Shakeable** - Import only what you need, minimize bundle size
20
+ - 🔒 **Zero Dependencies** - No supply chain risks, no version conflicts
21
+ - 💪 **Full TypeScript Support** - Complete type inference and safety
22
+ - ⚡ **Async-First** - Built-in support for promises and async operations
23
+ - 🧪 **Battle-Tested** - >95% test coverage, production-ready
24
+ - 🌐 **Isomorphic** - Works in both browser and Node.js environments
25
+
26
+ ## Installation
27
+
28
+ ::: code-group
29
+
30
+ ```bash [pnpm]
31
+ pnpm add @vielzeug/toolkit
32
+ ```
33
+
34
+ ```bash [npm]
35
+ npm install @vielzeug/toolkit
36
+ ```
37
+
38
+ ```bash [yarn]
39
+ yarn add @vielzeug/toolkit
40
+ ```
41
+
42
+ :::
43
+
44
+ ## Quick Start
45
+
46
+ ```typescript
47
+ import { chunk, map, retry, pool } from '@vielzeug/toolkit';
48
+
49
+ // Array operations
50
+ const batches = chunk([1, 2, 3, 4, 5], 2);
51
+ // [[1, 2], [3, 4], [5]]
52
+
53
+ // Async map with automatic Promise handling
54
+ const users = await map([1, 2, 3], async (id) => fetchUser(id));
55
+
56
+ // Retry with exponential backoff
57
+ const data = await retry(() => fetch('/api/data').then((r) => r.json()), { times: 3, delay: 1000, backoff: 2 });
58
+
59
+ // Rate limiting with promise pool
60
+ const apiPool = pool(5); // Max 5 concurrent requests
61
+ const results = await Promise.all(urls.map((url) => apiPool(() => fetch(url))));
62
+ ```
63
+
64
+ ## Categories
65
+
66
+ ### 📊 Array (25 utilities)
67
+
68
+ Transform, filter, group, and manipulate arrays with full type safety.
69
+
70
+ ```typescript
71
+ import { group, uniq, flatten, sort } from '@vielzeug/toolkit';
72
+
73
+ // Group by property
74
+ const grouped = group(users, (user) => user.role);
75
+
76
+ // Remove duplicates
77
+ const unique = uniq([1, 2, 2, 3, 3, 3]);
78
+
79
+ // Flatten nested arrays
80
+ const flat = flatten([
81
+ [1, 2],
82
+ [3, [4, 5]],
83
+ ]);
84
+
85
+ // Sort with custom comparator
86
+ const sorted = sort(items, (a, b) => a.price - b.price);
87
+ ```
88
+
89
+ **Available utilities:**
90
+ `aggregate`, `alternate`, `arrange`, `chunk`, `compact`, `contains`, `every`, `filter`, `find`, `findIndex`, `findLast`, `flatten`, `group`, `list`, `map`, `pick`, `reduce`, `remoteList`, `search`, `select`, `shift`, `some`, `sort`, `substitute`, `uniq`
91
+
92
+ ---
93
+
94
+ ### ⚡ Async (11 utilities)
95
+
96
+ Promise utilities, concurrency control, retries, and async patterns.
97
+
98
+ ```typescript
99
+ import { parallel, queue, waitFor, race, defer } from '@vielzeug/toolkit';
100
+
101
+ // Process with controlled concurrency
102
+ await parallel(3, urls, async (url) => fetch(url));
103
+
104
+ // Task queue with monitoring
105
+ const taskQueue = queue({ concurrency: 5 });
106
+ taskQueue.add(() => processTask());
107
+ await taskQueue.onIdle();
108
+
109
+ // Wait for condition
110
+ await waitFor(() => document.querySelector('#app') !== null);
111
+
112
+ // Race with minimum delay (better UX)
113
+ const data = await race(fetchData(), 500);
114
+
115
+ // Externally-controlled promise
116
+ const deferred = defer<string>();
117
+ setTimeout(() => deferred.resolve('Done!'), 1000);
118
+ ```
119
+
120
+ **Available utilities:**
121
+ `attempt`, `defer`, `delay`, `parallel`, `pool`, `predict`, `queue`, `race`, `retry`, `sleep`, `waitFor`
122
+
123
+ ---
124
+
125
+ ### 📅 Date (3 utilities)
126
+
127
+ Date manipulation and time calculations.
128
+
129
+ ```typescript
130
+ import { interval, timeDiff, expires } from '@vielzeug/toolkit';
131
+
132
+ // Calculate time intervals
133
+ const days = interval(new Date('2024-01-01'), new Date('2024-12-31'), 'days');
134
+
135
+ // Time difference
136
+ const diff = timeDiff(date1, date2);
137
+
138
+ // Check expiration
139
+ if (expires(expiryDate)) {
140
+ // Handle expired
141
+ }
142
+ ```
143
+
144
+ **Available utilities:**
145
+ `expires`, `interval`, `timeDiff`
146
+
147
+ ---
148
+
149
+ ### ⚙️ Function (14 utilities)
150
+
151
+ Function composition, memoization, and execution control.
152
+
153
+ ```typescript
154
+ import { debounce, throttle, memo, pipe, curry } from '@vielzeug/toolkit';
155
+
156
+ // Debounce user input
157
+ const search = debounce((query) => fetchResults(query), 300);
158
+
159
+ // Throttle scroll events
160
+ const onScroll = throttle(() => updateUI(), 100);
161
+
162
+ // Memoize expensive calculations
163
+ const fibonacci = memo((n) => (n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2)));
164
+
165
+ // Function composition
166
+ const transform = pipe(
167
+ (x) => x * 2,
168
+ (x) => x + 1,
169
+ (x) => x.toString(),
170
+ );
171
+
172
+ // Currying
173
+ const add = curry((a, b, c) => a + b + c);
174
+ const add5 = add(5);
175
+ ```
176
+
177
+ **Available utilities:**
178
+ `assert`, `assertParams`, `compare`, `compareBy`, `compose`, `curry`, `debounce`, `fp`, `memo`, `once`, `pipe`, `proxy`, `prune`, `throttle`, `worker`
179
+
180
+ ---
181
+
182
+ ### 🔢 Math (17 utilities)
183
+
184
+ Mathematical operations, statistics, and calculations.
185
+
186
+ ```typescript
187
+ import { average, median, clamp, range, distribute } from '@vielzeug/toolkit';
188
+
189
+ // Calculate average
190
+ const avg = average([1, 2, 3, 4, 5]); // 3
191
+
192
+ // Find median
193
+ const med = median([1, 2, 3, 4, 5]); // 3
194
+
195
+ // Clamp value to range
196
+ const clamped = clamp(150, 0, 100); // 100
197
+
198
+ // Generate range
199
+ const numbers = range(1, 10); // [1, 2, 3, ..., 10]
200
+
201
+ // Distribute amount
202
+ const shares = distribute(100, 3); // [33.33, 33.33, 33.34]
203
+ ```
204
+
205
+ **Available utilities:**
206
+ `abs`, `add`, `allocate`, `average`, `boil`, `clamp`, `distribute`, `divide`, `max`, `median`, `min`, `multiply`, `range`, `rate`, `round`, `subtract`, `sum`
207
+
208
+ ---
209
+
210
+ ### 💰 Money (3 utilities)
211
+
212
+ Currency formatting and exchange calculations.
213
+
214
+ ```typescript
215
+ import { currency, exchange } from '@vielzeug/toolkit';
216
+
217
+ // Format currency
218
+ const formatted = currency(1234.56, 'USD'); // "$1,234.56"
219
+
220
+ // Currency exchange
221
+ const converted = exchange(100, 'USD', 'EUR', 0.85); // 85
222
+ ```
223
+
224
+ **Available utilities:**
225
+ `currency`, `exchange`, `types`
226
+
227
+ ---
228
+
229
+ ### 📦 Object (10 utilities)
230
+
231
+ Deep merging, cloning, diffing, and object manipulation.
232
+
233
+ ```typescript
234
+ import { merge, clone, diff, path, seek } from '@vielzeug/toolkit';
235
+
236
+ // Deep merge
237
+ const merged = merge(obj1, obj2);
238
+
239
+ // Deep clone
240
+ const copy = clone(original);
241
+
242
+ // Diff objects
243
+ const changes = diff(oldObj, newObj);
244
+
245
+ // Get nested value
246
+ const value = path(obj, 'user.address.city');
247
+
248
+ // Search object
249
+ const results = seek(data, (val) => val > 100);
250
+ ```
251
+
252
+ **Available utilities:**
253
+ `cache`, `clone`, `diff`, `entries`, `keys`, `merge`, `parseJSON`, `path`, `seek`, `values`
254
+
255
+ ---
256
+
257
+ ### 🎲 Random (4 utilities)
258
+
259
+ Random values, shuffling, and UUID generation.
260
+
261
+ ```typescript
262
+ import { random, shuffle, draw, uuid } from '@vielzeug/toolkit';
263
+
264
+ // Random number
265
+ const num = random(1, 100);
266
+
267
+ // Shuffle array
268
+ const shuffled = shuffle([1, 2, 3, 4, 5]);
269
+
270
+ // Draw random items
271
+ const winners = draw(participants, 3);
272
+
273
+ // Generate UUID
274
+ const id = uuid(); // "550e8400-e29b-41d4-a716-446655440000"
275
+ ```
276
+
277
+ **Available utilities:**
278
+ `draw`, `random`, `shuffle`, `uuid`
279
+
280
+ ---
281
+
282
+ ### 📝 String (6 utilities)
283
+
284
+ String formatting, case conversion, and similarity.
285
+
286
+ ```typescript
287
+ import { camelCase, kebabCase, pascalCase, snakeCase, truncate, similarity } from '@vielzeug/toolkit';
288
+
289
+ // Case conversions
290
+ camelCase('hello world'); // "helloWorld"
291
+ kebabCase('hello world'); // "hello-world"
292
+ pascalCase('hello world'); // "HelloWorld"
293
+ snakeCase('hello world'); // "hello_world"
294
+
295
+ // Truncate text
296
+ truncate('Long text here', 10); // "Long text..."
297
+
298
+ // String similarity
299
+ similarity('hello', 'hallo'); // 0.8
300
+ ```
301
+
302
+ **Available utilities:**
303
+ `camelCase`, `kebabCase`, `pascalCase`, `similarity`, `snakeCase`, `truncate`
304
+
305
+ ---
306
+
307
+ ### ✅ Typed (27 utilities)
308
+
309
+ Type guards, type checking, and validation.
310
+
311
+ ```typescript
312
+ import { isString, isArray, isPromise, isEmpty, isEqual } from '@vielzeug/toolkit';
313
+
314
+ // Type guards with narrowing
315
+ if (isString(value)) {
316
+ // TypeScript knows value is string
317
+ console.log(value.toUpperCase());
318
+ }
319
+
320
+ // Check arrays
321
+ if (isArray(data)) {
322
+ data.forEach((item) => console.log(item));
323
+ }
324
+
325
+ // Promise detection
326
+ if (isPromise(result)) {
327
+ await result;
328
+ }
329
+
330
+ // Empty check
331
+ if (isEmpty(obj)) {
332
+ // Handle empty
333
+ }
334
+
335
+ // Deep equality
336
+ if (isEqual(obj1, obj2)) {
337
+ // Objects are equal
338
+ }
339
+ ```
340
+
341
+ **Available utilities:**
342
+ `ge`, `gt`, `is`, `isArray`, `isBoolean`, `isDate`, `isDefined`, `isEmpty`, `isEqual`, `isEven`, `isFunction`, `isNegative`, `isNil`, `isNumber`, `isObject`, `isOdd`, `isPositive`, `isPrimitive`, `isPromise`, `isRegex`, `isString`, `isWithin`, `isZero`, `le`, `lt`, `typeOf`
343
+
344
+ ## Real-World Examples
345
+
346
+ ### API Rate Limiting with Retry
347
+
348
+ ```typescript
349
+ import { pool, retry, predict } from '@vielzeug/toolkit';
350
+
351
+ // Create rate-limited pool
352
+ const apiPool = pool(10); // Max 10 concurrent requests
353
+
354
+ async function fetchWithRetry(url: string) {
355
+ return apiPool(() =>
356
+ retry(
357
+ () =>
358
+ predict(
359
+ async (signal) => {
360
+ const response = await fetch(url, { signal });
361
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
362
+ return response.json();
363
+ },
364
+ { timeout: 5000 },
365
+ ),
366
+ { times: 3, delay: 1000, backoff: 2 },
367
+ ),
368
+ );
369
+ }
370
+
371
+ // Process many URLs with rate limiting and retry
372
+ const results = await Promise.all(urls.map((url) => fetchWithRetry(url)));
373
+ ```
374
+
375
+ ### Batch Processing with Progress
376
+
377
+ ```typescript
378
+ import { chunk, parallel, sleep } from '@vielzeug/toolkit';
379
+
380
+ async function processBatch(items: any[], batchSize = 10) {
381
+ const batches = chunk(items, batchSize);
382
+ const results = [];
383
+
384
+ for (let i = 0; i < batches.length; i++) {
385
+ console.log(`Processing batch ${i + 1}/${batches.length}`);
386
+
387
+ const batchResults = await parallel(3, batches[i], async (item) => {
388
+ return await processItem(item);
389
+ });
390
+
391
+ results.push(...batchResults);
392
+
393
+ // Delay between batches
394
+ if (i < batches.length - 1) {
395
+ await sleep(1000);
396
+ }
397
+ }
398
+
399
+ return results;
400
+ }
401
+ ```
402
+
403
+ ### Form Validation Pipeline
404
+
405
+ ```typescript
406
+ import { pipe, curry, isEmpty, isString } from '@vielzeug/toolkit';
407
+
408
+ const required = (value: any) => {
409
+ if (isEmpty(value)) throw new Error('Required field');
410
+ return value;
411
+ };
412
+
413
+ const minLength = curry((min: number, value: string) => {
414
+ if (!isString(value) || value.length < min) {
415
+ throw new Error(`Minimum ${min} characters`);
416
+ }
417
+ return value;
418
+ });
419
+
420
+ const email = (value: string) => {
421
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
422
+ throw new Error('Invalid email');
423
+ }
424
+ return value;
425
+ };
426
+
427
+ // Create validation pipeline
428
+ const validateEmail = pipe(required, minLength(5), email);
429
+
430
+ try {
431
+ const validEmail = validateEmail(userInput);
432
+ } catch (error) {
433
+ console.error(error.message);
434
+ }
435
+ ```
436
+
437
+ ## Performance & Bundle Size
438
+
439
+ ### Tree-Shaking
440
+
441
+ Toolkit is designed for optimal tree-shaking. Import only what you use:
442
+
443
+ ```typescript
444
+ // ✅ Good - Only includes chunk function (~0.5KB gzipped)
445
+ import { chunk } from '@vielzeug/toolkit';
446
+
447
+ // ⚠️ Avoid - Imports entire library (~35KB gzipped)
448
+ import * as toolkit from '@vielzeug/toolkit';
449
+ ```
450
+
451
+ ### Bundle Size by Category
452
+
453
+ | Category | Utilities | Approx. Size (gzipped) |
454
+ | -------- | --------- | ---------------------- |
455
+ | Array | 25 | ~8KB |
456
+ | Async | 11 | ~3KB |
457
+ | Date | 3 | ~1KB |
458
+ | Function | 14 | ~5KB |
459
+ | Math | 17 | ~4KB |
460
+ | Money | 3 | ~1KB |
461
+ | Object | 10 | ~3KB |
462
+ | Random | 4 | ~1KB |
463
+ | String | 6 | ~2KB |
464
+ | Typed | 27 | ~3KB |
465
+
466
+ > **Note**: Individual utilities are typically **0.1-0.8 KB gzipped** each.
467
+
468
+ ## TypeScript Support
469
+
470
+ Full TypeScript support with complete type inference:
471
+
472
+ ```typescript
473
+ import { map, filter, group } from '@vielzeug/toolkit';
474
+
475
+ const numbers = [1, 2, 3, 4, 5];
476
+
477
+ // Type inferred as number[]
478
+ const doubled = map(numbers, (n) => n * 2);
479
+
480
+ // Type inferred as number[]
481
+ const evens = filter(numbers, (n) => n % 2 === 0);
482
+
483
+ // Type inferred as Record<string, User[]>
484
+ const byRole = group(users, (u) => u.role);
485
+
486
+ // Async operations automatically return Promise
487
+ const results = await map(ids, async (id) => fetchUser(id));
488
+ // Type: Promise<User[]>
489
+ ```
490
+
491
+ ## Comparison with Alternatives
492
+
493
+ | Feature | Toolkit | Lodash | Ramda | Native JS |
494
+ | ---------------------- | ---------------- | ----------------- | ----------------- | ---------- |
495
+ | TypeScript Support | ✅ First-class | ⚠️ Via @types | ⚠️ Via @types | ❌ Limited |
496
+ | Tree-shakeable | ✅ By default | ⚠️ lodash-es only | ✅ Yes | N/A |
497
+ | Bundle Size (min+gzip) | ~0.1-1KB/utility | ~24KB (full) | ~12KB (full) | 0KB |
498
+ | Dependencies | 0 | 0 | 0 | N/A |
499
+ | Async Support | ✅ Built-in | ❌ Limited | ❌ Limited | ⚠️ Manual |
500
+ | Learning Curve | Low | Low | High (FP focused) | Low |
501
+
502
+ ## Documentation
503
+
504
+ - **[Full Documentation](https://helmuthdu.github.io/vielzeug/toolkit/)**
505
+ - **[API Reference](https://helmuthdu.github.io/vielzeug/toolkit/api)**
506
+ - **[Usage Guide](https://helmuthdu.github.io/vielzeug/toolkit/usage)**
507
+ - **[Examples](https://helmuthdu.github.io/vielzeug/toolkit/examples/array)**
508
+
509
+ ## Contributing
510
+
511
+ We welcome contributions! Please see our [Contributing Guide](../../CONTRIBUTING.md) for details.
512
+
513
+ ### Development
514
+
515
+ ```bash
516
+ # Install dependencies
517
+ pnpm install
518
+
519
+ # Build the package
520
+ pnpm build
521
+
522
+ # Run tests
523
+ pnpm test
524
+
525
+ # Run tests in watch mode
526
+ pnpm test:watch
527
+
528
+ # Type check
529
+ pnpm typecheck
530
+ ```
531
+
532
+ ## License
533
+
534
+ MIT © [Helmuth Saatkamp](https://github.com/helmuthdu/vielzeug)
535
+
536
+ ## Related Packages
537
+
538
+ Part of the [@vielzeug](https://helmuthdu.github.io/vielzeug/) monorepo:
539
+
540
+ - **[@vielzeug/deposit](../deposit)** - Type-safe local storage with schemas and expiration
541
+ - **[@vielzeug/fetchit](../fetchit)** - Advanced HTTP client with caching and retries
542
+ - **[@vielzeug/formit](../formit)** - Type-safe form state and validation
543
+ - **[@vielzeug/i18nit](../i18nit)** - Internationalization with TypeScript
544
+ - **[@vielzeug/logit](../logit)** - Beautiful console logging
545
+ - **[@vielzeug/permit](../permit)** - Role-based access control
546
+ - **[@vielzeug/validit](../validit)** - Type-safe validation schemas
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attempt.cjs","sources":["../../src/async/attempt.ts"],"sourcesContent":["import { Logit } from '@vielzeug/logit';\nimport type { Fn } from '../types';\nimport { predict } from './predict';\nimport { retry } from './retry';\n\ntype AttemptOptions = {\n identifier?: string;\n retries?: number;\n silent?: boolean;\n timeout?: number;\n};\n\n/**\n * Attempts to execute a function with advanced error handling and retry logic.\n *\n * @example\n * ```ts\n * const unreliableFunction = async () => {\n * if (Math.random() < 0.7) throw new Error ('Random failure');\n * return 'Success!';\n * };\n *\n * await attempt(\n * unreliableFunction,\n * { retries: 3, silent: false, timeout: 5000 }); // Success! (or undefined if all attempts failed)\n * ```\n *\n * @param fn - The function to be executed.\n * @param [options] - Configuration options for the attempt.\n * @param [options.identifier] - Custom identifier for logging purposes.\n * @param [options.retries=0] - Number of retry attempts if the function fails.\n * @param [options.silent=false] - If true, suppresses error logging.\n * @param [options.timeout=7000] - Timeout in milliseconds for function execution.\n *\n * @returns The result of the function or undefined if it failed.\n */\nexport async function attempt<T extends Fn, R = Awaited<ReturnType<T>>>(\n fn: T,\n { silent = false, retries = 0, timeout = 7000, identifier = fn.name || 'anonymous function' }: AttemptOptions = {},\n): Promise<R | undefined> {\n try {\n return await retry(() => predict<R>(() => fn(), { timeout }), { times: retries + 1 });\n } catch (err) {\n if (!silent) {\n Logit.error(`attempt(${identifier}) -> all attempts failed`, { cause: err });\n }\n return undefined;\n }\n}\n"],"names":["attempt","fn","silent","retries","timeout","identifier","retry","predict","err","Logit"],"mappings":"+KAoCA,eAAsBA,EACpBC,EACA,CAAE,OAAAC,EAAS,GAAO,QAAAC,EAAU,EAAG,QAAAC,EAAU,IAAM,WAAAC,EAAaJ,EAAG,MAAQ,oBAAA,EAAyC,CAAA,EACxF,CACxB,GAAI,CACF,OAAO,MAAMK,EAAAA,MAAM,IAAMC,EAAAA,QAAW,IAAMN,EAAA,EAAM,CAAE,QAAAG,CAAA,CAAS,EAAG,CAAE,MAAOD,EAAU,EAAG,CACtF,OAASK,EAAK,CACPN,GACHO,QAAM,MAAM,WAAWJ,CAAU,2BAA4B,CAAE,MAAOG,EAAK,EAE7E,MACF,CACF"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attempt.js","sources":["../../src/async/attempt.ts"],"sourcesContent":["import { Logit } from '@vielzeug/logit';\nimport type { Fn } from '../types';\nimport { predict } from './predict';\nimport { retry } from './retry';\n\ntype AttemptOptions = {\n identifier?: string;\n retries?: number;\n silent?: boolean;\n timeout?: number;\n};\n\n/**\n * Attempts to execute a function with advanced error handling and retry logic.\n *\n * @example\n * ```ts\n * const unreliableFunction = async () => {\n * if (Math.random() < 0.7) throw new Error ('Random failure');\n * return 'Success!';\n * };\n *\n * await attempt(\n * unreliableFunction,\n * { retries: 3, silent: false, timeout: 5000 }); // Success! (or undefined if all attempts failed)\n * ```\n *\n * @param fn - The function to be executed.\n * @param [options] - Configuration options for the attempt.\n * @param [options.identifier] - Custom identifier for logging purposes.\n * @param [options.retries=0] - Number of retry attempts if the function fails.\n * @param [options.silent=false] - If true, suppresses error logging.\n * @param [options.timeout=7000] - Timeout in milliseconds for function execution.\n *\n * @returns The result of the function or undefined if it failed.\n */\nexport async function attempt<T extends Fn, R = Awaited<ReturnType<T>>>(\n fn: T,\n { silent = false, retries = 0, timeout = 7000, identifier = fn.name || 'anonymous function' }: AttemptOptions = {},\n): Promise<R | undefined> {\n try {\n return await retry(() => predict<R>(() => fn(), { timeout }), { times: retries + 1 });\n } catch (err) {\n if (!silent) {\n Logit.error(`attempt(${identifier}) -> all attempts failed`, { cause: err });\n }\n return undefined;\n }\n}\n"],"names":["attempt","fn","silent","retries","timeout","identifier","retry","predict","err","Logit"],"mappings":";;;AAoCA,eAAsBA,EACpBC,GACA,EAAE,QAAAC,IAAS,IAAO,SAAAC,IAAU,GAAG,SAAAC,IAAU,KAAM,YAAAC,IAAaJ,EAAG,QAAQ,qBAAA,IAAyC,CAAA,GACxF;AACxB,MAAI;AACF,WAAO,MAAMK,EAAM,MAAMC,EAAW,MAAMN,EAAA,GAAM,EAAE,SAAAG,EAAA,CAAS,GAAG,EAAE,OAAOD,IAAU,GAAG;AAAA,EACtF,SAASK,GAAK;AACZ,IAAKN,KACHO,EAAM,MAAM,WAAWJ,CAAU,4BAA4B,EAAE,OAAOG,GAAK;AAE7E;AAAA,EACF;AACF;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function i(){let e,r;return{promise:new Promise((t,o)=>{e=t,r=o}),reject:r,resolve:e}}exports.defer=i;
2
+ //# sourceMappingURL=defer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defer.cjs","sources":["../../src/async/defer.ts"],"sourcesContent":["/**\n * Creates a deferred promise with resolve and reject methods exposed.\n * Useful for creating promises that are resolved/rejected externally.\n *\n * @example\n * ```ts\n * const deferred = defer<string>();\n *\n * setTimeout(() => {\n * deferred.resolve('Done!');\n * }, 1000);\n *\n * const result = await deferred.promise; // 'Done!'\n * ```\n *\n * @returns Object with promise and resolve/reject methods\n */\nexport function defer<T = void>(): {\n promise: Promise<T>;\n resolve: (value: T | PromiseLike<T>) => void;\n reject: (reason?: unknown) => void;\n} {\n let resolve!: (value: T | PromiseLike<T>) => void;\n let reject!: (reason?: unknown) => void;\n\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n return { promise, reject, resolve };\n}\n"],"names":["defer","resolve","reject","res","rej"],"mappings":"gFAiBO,SAASA,GAId,CACA,IAAIC,EACAC,EAOJ,MAAO,CAAE,QALO,IAAI,QAAW,CAACC,EAAKC,IAAQ,CAC3CH,EAAUE,EACVD,EAASE,CACX,CAAC,EAEiB,OAAAF,EAAQ,QAAAD,CAAA,CAC5B"}
@@ -0,0 +1,10 @@
1
+ function s() {
2
+ let e, r;
3
+ return { promise: new Promise((o, t) => {
4
+ e = o, r = t;
5
+ }), reject: r, resolve: e };
6
+ }
7
+ export {
8
+ s as defer
9
+ };
10
+ //# sourceMappingURL=defer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defer.js","sources":["../../src/async/defer.ts"],"sourcesContent":["/**\n * Creates a deferred promise with resolve and reject methods exposed.\n * Useful for creating promises that are resolved/rejected externally.\n *\n * @example\n * ```ts\n * const deferred = defer<string>();\n *\n * setTimeout(() => {\n * deferred.resolve('Done!');\n * }, 1000);\n *\n * const result = await deferred.promise; // 'Done!'\n * ```\n *\n * @returns Object with promise and resolve/reject methods\n */\nexport function defer<T = void>(): {\n promise: Promise<T>;\n resolve: (value: T | PromiseLike<T>) => void;\n reject: (reason?: unknown) => void;\n} {\n let resolve!: (value: T | PromiseLike<T>) => void;\n let reject!: (reason?: unknown) => void;\n\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n return { promise, reject, resolve };\n}\n"],"names":["defer","resolve","reject","res","rej"],"mappings":"AAiBO,SAASA,IAId;AACA,MAAIC,GACAC;AAOJ,SAAO,EAAE,SALO,IAAI,QAAW,CAACC,GAAKC,MAAQ;AAC3C,IAAAH,IAAUE,GACVD,IAASE;AAAA,EACX,CAAC,GAEiB,QAAAF,GAAQ,SAAAD,EAAA;AAC5B;"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delay.cjs","sources":["../../src/async/delay.ts"],"sourcesContent":["import type { Fn } from '../types';\nimport { sleep } from './sleep';\n\n/**\n * Delays the execution of a function by a specified amount of time.\n *\n * @example\n * ```ts\n * const log = () => console.log('Hello, world!');\n *\n * delay(log, 1000); // logs 'Hello, world!' after 1 second\n * ```\n *\n * @param fn - The function to be delayed.\n * @param delay - The amount of time to delay the function execution, in milliseconds. Default is 700.\n *\n * @returns A Promise that resolves with the result of the function execution.\n */\nexport async function delay<T extends Fn>(fn: T, delay = 700) {\n await sleep(delay);\n\n return fn();\n}\n"],"names":["delay","fn","sleep"],"mappings":"+GAkBA,eAAsBA,EAAoBC,EAAOD,EAAQ,IAAK,CAC5D,aAAME,EAAAA,MAAMF,CAAK,EAEVC,EAAA,CACT"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delay.js","sources":["../../src/async/delay.ts"],"sourcesContent":["import type { Fn } from '../types';\nimport { sleep } from './sleep';\n\n/**\n * Delays the execution of a function by a specified amount of time.\n *\n * @example\n * ```ts\n * const log = () => console.log('Hello, world!');\n *\n * delay(log, 1000); // logs 'Hello, world!' after 1 second\n * ```\n *\n * @param fn - The function to be delayed.\n * @param delay - The amount of time to delay the function execution, in milliseconds. Default is 700.\n *\n * @returns A Promise that resolves with the result of the function execution.\n */\nexport async function delay<T extends Fn>(fn: T, delay = 700) {\n await sleep(delay);\n\n return fn();\n}\n"],"names":["delay","fn","sleep"],"mappings":";AAkBA,eAAsBA,EAAoBC,GAAOD,IAAQ,KAAK;AAC5D,eAAME,EAAMF,CAAK,GAEVC,EAAA;AACT;"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel.cjs","sources":["../../src/async/parallel.ts"],"sourcesContent":["/**\n * Processes an array with an async callback with controlled parallelism.\n * Similar to Promise.all, but limits how many items are processed concurrently.\n * Returns an ordered array of results.\n *\n * @example\n * ```ts\n * // Process 3 items at a time\n * const results = await parallel(3, [1, 2, 3, 4, 5], async (n) => {\n * await delay(100);\n * return n * 2;\n * });\n * // [2, 4, 6, 8, 10]\n *\n * // With abort signal\n * const controller = new AbortController();\n * const results = await parallel(2, items, async (item) => {\n * return processItem(item);\n * }, controller.signal);\n * ```\n *\n * @param limit - Maximum number of concurrent operations (must be >= 1)\n * @param array - Array of items to process\n * @param callback - Async function to process each item\n * @param signal - Optional AbortSignal to cancel processing\n * @returns Promise resolving to an ordered array of results\n * @throws {Error} If limit is less than 1\n * @throws {DOMException} If aborted via signal\n */\nexport async function parallel<T, R>(\n limit: number,\n array: T[],\n callback: (item: T, index: number, array: T[]) => Promise<R>,\n signal?: AbortSignal,\n): Promise<R[]> {\n if (limit < 1) {\n throw new Error('Limit must be at least 1');\n }\n\n if (signal?.aborted) {\n throw new DOMException('Aborted', 'AbortError');\n }\n\n const results: R[] = new Array(array.length);\n let currentIndex = 0;\n let hasError = false;\n let error: unknown;\n\n // Check for abort\n const checkAbort = () => {\n if (signal?.aborted) {\n hasError = true;\n error = new DOMException('Aborted', 'AbortError');\n return true;\n }\n return false;\n };\n\n // Worker function that processes items from the queue\n const worker = async (): Promise<void> => {\n while (currentIndex < array.length && !hasError) {\n if (checkAbort()) {\n break;\n }\n\n const index = currentIndex++;\n\n try {\n results[index] = await callback(array[index], index, array);\n } catch (err) {\n hasError = true;\n error = err;\n break;\n }\n }\n };\n\n // Create workers up to the limit\n const workers: Promise<void>[] = [];\n const workerCount = Math.min(limit, array.length);\n\n for (let i = 0; i < workerCount; i++) {\n workers.push(worker());\n }\n\n // Wait for all workers to complete\n await Promise.all(workers);\n\n // If there was an error, throw it\n if (hasError) {\n throw error;\n }\n\n return results;\n}\n"],"names":["parallel","limit","array","callback","signal","results","currentIndex","hasError","error","checkAbort","worker","index","err","workers","workerCount","i"],"mappings":"gFA6BA,eAAsBA,EACpBC,EACAC,EACAC,EACAC,EACc,CACd,GAAIH,EAAQ,EACV,MAAM,IAAI,MAAM,0BAA0B,EAG5C,GAAIG,GAAQ,QACV,MAAM,IAAI,aAAa,UAAW,YAAY,EAGhD,MAAMC,EAAe,IAAI,MAAMH,EAAM,MAAM,EAC3C,IAAII,EAAe,EACfC,EAAW,GACXC,EAGJ,MAAMC,EAAa,IACbL,GAAQ,SACVG,EAAW,GACXC,EAAQ,IAAI,aAAa,UAAW,YAAY,EACzC,IAEF,GAIHE,EAAS,SAA2B,CACxC,KAAOJ,EAAeJ,EAAM,QAAU,CAACK,GACjC,CAAAE,KAD2C,CAK/C,MAAME,EAAQL,IAEd,GAAI,CACFD,EAAQM,CAAK,EAAI,MAAMR,EAASD,EAAMS,CAAK,EAAGA,EAAOT,CAAK,CAC5D,OAASU,EAAK,CACZL,EAAW,GACXC,EAAQI,EACR,KACF,CACF,CACF,EAGMC,EAA2B,CAAA,EAC3BC,EAAc,KAAK,IAAIb,EAAOC,EAAM,MAAM,EAEhD,QAASa,EAAI,EAAGA,EAAID,EAAaC,IAC/BF,EAAQ,KAAKH,GAAQ,EAOvB,GAHA,MAAM,QAAQ,IAAIG,CAAO,EAGrBN,EACF,MAAMC,EAGR,OAAOH,CACT"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel.js","sources":["../../src/async/parallel.ts"],"sourcesContent":["/**\n * Processes an array with an async callback with controlled parallelism.\n * Similar to Promise.all, but limits how many items are processed concurrently.\n * Returns an ordered array of results.\n *\n * @example\n * ```ts\n * // Process 3 items at a time\n * const results = await parallel(3, [1, 2, 3, 4, 5], async (n) => {\n * await delay(100);\n * return n * 2;\n * });\n * // [2, 4, 6, 8, 10]\n *\n * // With abort signal\n * const controller = new AbortController();\n * const results = await parallel(2, items, async (item) => {\n * return processItem(item);\n * }, controller.signal);\n * ```\n *\n * @param limit - Maximum number of concurrent operations (must be >= 1)\n * @param array - Array of items to process\n * @param callback - Async function to process each item\n * @param signal - Optional AbortSignal to cancel processing\n * @returns Promise resolving to an ordered array of results\n * @throws {Error} If limit is less than 1\n * @throws {DOMException} If aborted via signal\n */\nexport async function parallel<T, R>(\n limit: number,\n array: T[],\n callback: (item: T, index: number, array: T[]) => Promise<R>,\n signal?: AbortSignal,\n): Promise<R[]> {\n if (limit < 1) {\n throw new Error('Limit must be at least 1');\n }\n\n if (signal?.aborted) {\n throw new DOMException('Aborted', 'AbortError');\n }\n\n const results: R[] = new Array(array.length);\n let currentIndex = 0;\n let hasError = false;\n let error: unknown;\n\n // Check for abort\n const checkAbort = () => {\n if (signal?.aborted) {\n hasError = true;\n error = new DOMException('Aborted', 'AbortError');\n return true;\n }\n return false;\n };\n\n // Worker function that processes items from the queue\n const worker = async (): Promise<void> => {\n while (currentIndex < array.length && !hasError) {\n if (checkAbort()) {\n break;\n }\n\n const index = currentIndex++;\n\n try {\n results[index] = await callback(array[index], index, array);\n } catch (err) {\n hasError = true;\n error = err;\n break;\n }\n }\n };\n\n // Create workers up to the limit\n const workers: Promise<void>[] = [];\n const workerCount = Math.min(limit, array.length);\n\n for (let i = 0; i < workerCount; i++) {\n workers.push(worker());\n }\n\n // Wait for all workers to complete\n await Promise.all(workers);\n\n // If there was an error, throw it\n if (hasError) {\n throw error;\n }\n\n return results;\n}\n"],"names":["parallel","limit","array","callback","signal","results","currentIndex","hasError","error","checkAbort","worker","index","err","workers","workerCount","i"],"mappings":"AA6BA,eAAsBA,EACpBC,GACAC,GACAC,GACAC,GACc;AACd,MAAIH,IAAQ;AACV,UAAM,IAAI,MAAM,0BAA0B;AAG5C,MAAIG,GAAQ;AACV,UAAM,IAAI,aAAa,WAAW,YAAY;AAGhD,QAAMC,IAAe,IAAI,MAAMH,EAAM,MAAM;AAC3C,MAAII,IAAe,GACfC,IAAW,IACXC;AAGJ,QAAMC,IAAa,MACbL,GAAQ,WACVG,IAAW,IACXC,IAAQ,IAAI,aAAa,WAAW,YAAY,GACzC,MAEF,IAIHE,IAAS,YAA2B;AACxC,WAAOJ,IAAeJ,EAAM,UAAU,CAACK,KACjC,CAAAE,OAD2C;AAK/C,YAAME,IAAQL;AAEd,UAAI;AACF,QAAAD,EAAQM,CAAK,IAAI,MAAMR,EAASD,EAAMS,CAAK,GAAGA,GAAOT,CAAK;AAAA,MAC5D,SAASU,GAAK;AACZ,QAAAL,IAAW,IACXC,IAAQI;AACR;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAGMC,IAA2B,CAAA,GAC3BC,IAAc,KAAK,IAAIb,GAAOC,EAAM,MAAM;AAEhD,WAASa,IAAI,GAAGA,IAAID,GAAaC;AAC/B,IAAAF,EAAQ,KAAKH,GAAQ;AAOvB,MAHA,MAAM,QAAQ,IAAIG,CAAO,GAGrBN;AACF,UAAMC;AAGR,SAAOH;AACT;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("../function/assert.cjs");function u(e){a.assert(e>=1,"Pool limit must be at least 1",{args:{limit:e},type:RangeError});let t=0;const n=[],r=()=>{n.length>0&&t<e&&n.shift()?.()};return async o=>{for(;t>=e;)await new Promise(s=>n.push(s));t++;try{return await o()}finally{t--,r()}}}exports.pool=u;
2
+ //# sourceMappingURL=pool.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool.cjs","sources":["../../src/async/pool.ts"],"sourcesContent":["import { assert } from '../function/assert';\n\n/**\n * Creates a promise pool that limits the number of concurrent promises.\n * Useful for rate limiting API calls or controlling resource usage.\n *\n * @example\n * ```ts\n * const requestPool = pool(3);\n *\n * const results = await Promise.all([\n * requestPool(() => fetch('/api/1')),\n * requestPool(() => fetch('/api/2')),\n * requestPool(() => fetch('/api/3')),\n * requestPool(() => fetch('/api/4')), // Will wait for one of the above to finish\n * ]);\n * ```\n *\n * @param limit - Maximum number of concurrent promises\n * @returns Function that accepts a promise-returning function and executes it when a slot is available\n */\nexport function pool(limit: number): <T>(fn: () => Promise<T>) => Promise<T> {\n assert(limit >= 1, 'Pool limit must be at least 1', { args: { limit }, type: RangeError });\n\n let activeCount = 0;\n const queue: Array<() => void> = [];\n\n const dequeue = (): void => {\n if (queue.length > 0 && activeCount < limit) {\n const next = queue.shift();\n next?.();\n }\n };\n\n return async <T>(fn: () => Promise<T>): Promise<T> => {\n while (activeCount >= limit) {\n await new Promise<void>((resolve) => queue.push(resolve));\n }\n\n activeCount++;\n\n try {\n return await fn();\n } finally {\n activeCount--;\n dequeue();\n }\n };\n}\n"],"names":["pool","limit","assert","activeCount","queue","dequeue","fn","resolve"],"mappings":"0HAqBO,SAASA,EAAKC,EAAwD,CAC3EC,SAAOD,GAAS,EAAG,gCAAiC,CAAE,KAAM,CAAE,MAAAA,CAAA,EAAS,KAAM,WAAY,EAEzF,IAAIE,EAAc,EAClB,MAAMC,EAA2B,CAAA,EAE3BC,EAAU,IAAY,CACtBD,EAAM,OAAS,GAAKD,EAAcF,GACvBG,EAAM,MAAA,IACnB,CAEJ,EAEA,MAAO,OAAUE,GAAqC,CACpD,KAAOH,GAAeF,GACpB,MAAM,IAAI,QAAeM,GAAYH,EAAM,KAAKG,CAAO,CAAC,EAG1DJ,IAEA,GAAI,CACF,OAAO,MAAMG,EAAA,CACf,QAAA,CACEH,IACAE,EAAA,CACF,CACF,CACF"}
@@ -0,0 +1,22 @@
1
+ import { assert as s } from "../function/assert.js";
2
+ function c(e) {
3
+ s(e >= 1, "Pool limit must be at least 1", { args: { limit: e }, type: RangeError });
4
+ let t = 0;
5
+ const n = [], r = () => {
6
+ n.length > 0 && t < e && n.shift()?.();
7
+ };
8
+ return async (o) => {
9
+ for (; t >= e; )
10
+ await new Promise((a) => n.push(a));
11
+ t++;
12
+ try {
13
+ return await o();
14
+ } finally {
15
+ t--, r();
16
+ }
17
+ };
18
+ }
19
+ export {
20
+ c as pool
21
+ };
22
+ //# sourceMappingURL=pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool.js","sources":["../../src/async/pool.ts"],"sourcesContent":["import { assert } from '../function/assert';\n\n/**\n * Creates a promise pool that limits the number of concurrent promises.\n * Useful for rate limiting API calls or controlling resource usage.\n *\n * @example\n * ```ts\n * const requestPool = pool(3);\n *\n * const results = await Promise.all([\n * requestPool(() => fetch('/api/1')),\n * requestPool(() => fetch('/api/2')),\n * requestPool(() => fetch('/api/3')),\n * requestPool(() => fetch('/api/4')), // Will wait for one of the above to finish\n * ]);\n * ```\n *\n * @param limit - Maximum number of concurrent promises\n * @returns Function that accepts a promise-returning function and executes it when a slot is available\n */\nexport function pool(limit: number): <T>(fn: () => Promise<T>) => Promise<T> {\n assert(limit >= 1, 'Pool limit must be at least 1', { args: { limit }, type: RangeError });\n\n let activeCount = 0;\n const queue: Array<() => void> = [];\n\n const dequeue = (): void => {\n if (queue.length > 0 && activeCount < limit) {\n const next = queue.shift();\n next?.();\n }\n };\n\n return async <T>(fn: () => Promise<T>): Promise<T> => {\n while (activeCount >= limit) {\n await new Promise<void>((resolve) => queue.push(resolve));\n }\n\n activeCount++;\n\n try {\n return await fn();\n } finally {\n activeCount--;\n dequeue();\n }\n };\n}\n"],"names":["pool","limit","assert","activeCount","queue","dequeue","fn","resolve"],"mappings":";AAqBO,SAASA,EAAKC,GAAwD;AAC3E,EAAAC,EAAOD,KAAS,GAAG,iCAAiC,EAAE,MAAM,EAAE,OAAAA,EAAA,GAAS,MAAM,YAAY;AAEzF,MAAIE,IAAc;AAClB,QAAMC,IAA2B,CAAA,GAE3BC,IAAU,MAAY;AAC1B,IAAID,EAAM,SAAS,KAAKD,IAAcF,KACvBG,EAAM,MAAA,IACnB;AAAA,EAEJ;AAEA,SAAO,OAAUE,MAAqC;AACpD,WAAOH,KAAeF;AACpB,YAAM,IAAI,QAAc,CAACM,MAAYH,EAAM,KAAKG,CAAO,CAAC;AAG1D,IAAAJ;AAEA,QAAI;AACF,aAAO,MAAMG,EAAA;AAAA,IACf,UAAA;AACE,MAAAH,KACAE,EAAA;AAAA,IACF;AAAA,EACF;AACF;"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"predict.cjs","sources":["../../src/async/predict.ts"],"sourcesContent":["/**\n * Creates a Promise that can be aborted using an AbortController.\n *\n * @example\n * ```ts\n * const slowFn = () => new Promise(resolve => setTimeout(() => resolve('slow'), 10000));\n * const fastFn = () => new Promise(resolve => setTimeout(() => resolve('fast'), 5000));\n *\n * predict(slowFn); // rejects after 7 seconds\n * predict(fastFn); // resolves with 'fast' after 5 seconds\n * ```\n *\n * @param fn - The function to execute, which receives an AbortSignal.\n * @param options - The options for the abortable function.\n * @param [options.signal] - The AbortSignal to use for aborting the Promise.\n * @param [options.timeout=7000] - The timeout in milliseconds after which the Promise will be aborted.\n *\n * @returns - A Promise that resolves with the result of the callback or rejects if aborted.\n */\nexport function predict<T>(\n fn: (signal: AbortSignal) => Promise<T>,\n options: { signal?: AbortSignal; timeout?: number } = {},\n): Promise<T> {\n const { signal, timeout = 7000 } = options;\n const abortSignal = signal ? AbortSignal.any([AbortSignal.timeout(timeout), signal]) : AbortSignal.timeout(timeout);\n\n return Promise.race([\n fn(abortSignal),\n new Promise<never>((_, reject) => {\n abortSignal.addEventListener('abort', () => reject(new Error('Operation aborted')), { once: true });\n }),\n ]);\n}\n"],"names":["predict","fn","options","signal","timeout","abortSignal","_","reject"],"mappings":"gFAmBO,SAASA,EACdC,EACAC,EAAsD,GAC1C,CACZ,KAAM,CAAE,OAAAC,EAAQ,QAAAC,EAAU,GAAA,EAASF,EAC7BG,EAAcF,EAAS,YAAY,IAAI,CAAC,YAAY,QAAQC,CAAO,EAAGD,CAAM,CAAC,EAAI,YAAY,QAAQC,CAAO,EAElH,OAAO,QAAQ,KAAK,CAClBH,EAAGI,CAAW,EACd,IAAI,QAAe,CAACC,EAAGC,IAAW,CAChCF,EAAY,iBAAiB,QAAS,IAAME,EAAO,IAAI,MAAM,mBAAmB,CAAC,EAAG,CAAE,KAAM,EAAA,CAAM,CACpG,CAAC,CAAA,CACF,CACH"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"predict.js","sources":["../../src/async/predict.ts"],"sourcesContent":["/**\n * Creates a Promise that can be aborted using an AbortController.\n *\n * @example\n * ```ts\n * const slowFn = () => new Promise(resolve => setTimeout(() => resolve('slow'), 10000));\n * const fastFn = () => new Promise(resolve => setTimeout(() => resolve('fast'), 5000));\n *\n * predict(slowFn); // rejects after 7 seconds\n * predict(fastFn); // resolves with 'fast' after 5 seconds\n * ```\n *\n * @param fn - The function to execute, which receives an AbortSignal.\n * @param options - The options for the abortable function.\n * @param [options.signal] - The AbortSignal to use for aborting the Promise.\n * @param [options.timeout=7000] - The timeout in milliseconds after which the Promise will be aborted.\n *\n * @returns - A Promise that resolves with the result of the callback or rejects if aborted.\n */\nexport function predict<T>(\n fn: (signal: AbortSignal) => Promise<T>,\n options: { signal?: AbortSignal; timeout?: number } = {},\n): Promise<T> {\n const { signal, timeout = 7000 } = options;\n const abortSignal = signal ? AbortSignal.any([AbortSignal.timeout(timeout), signal]) : AbortSignal.timeout(timeout);\n\n return Promise.race([\n fn(abortSignal),\n new Promise<never>((_, reject) => {\n abortSignal.addEventListener('abort', () => reject(new Error('Operation aborted')), { once: true });\n }),\n ]);\n}\n"],"names":["predict","fn","options","signal","timeout","abortSignal","_","reject"],"mappings":"AAmBO,SAASA,EACdC,GACAC,IAAsD,IAC1C;AACZ,QAAM,EAAE,QAAAC,GAAQ,SAAAC,IAAU,IAAA,IAASF,GAC7BG,IAAcF,IAAS,YAAY,IAAI,CAAC,YAAY,QAAQC,CAAO,GAAGD,CAAM,CAAC,IAAI,YAAY,QAAQC,CAAO;AAElH,SAAO,QAAQ,KAAK;AAAA,IAClBH,EAAGI,CAAW;AAAA,IACd,IAAI,QAAe,CAACC,GAAGC,MAAW;AAChC,MAAAF,EAAY,iBAAiB,SAAS,MAAME,EAAO,IAAI,MAAM,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAA,CAAM;AAAA,IACpG,CAAC;AAAA,EAAA,CACF;AACH;"}