speexjs-core 0.7.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 (78) hide show
  1. package/CHANGELOG.md +117 -0
  2. package/CONTRIBUTING.md +55 -0
  3. package/PUBLISH.md +45 -0
  4. package/README.md +174 -0
  5. package/ROADMAP.md +72 -0
  6. package/SECURITY.md +35 -0
  7. package/SUMMARY.md +321 -0
  8. package/dist/async/index.d.ts +232 -0
  9. package/dist/async/index.js +366 -0
  10. package/dist/async/index.js.map +1 -0
  11. package/dist/collection/index.d.ts +230 -0
  12. package/dist/collection/index.js +375 -0
  13. package/dist/collection/index.js.map +1 -0
  14. package/dist/color/index.d.ts +128 -0
  15. package/dist/color/index.js +167 -0
  16. package/dist/color/index.js.map +1 -0
  17. package/dist/core/index.d.ts +119 -0
  18. package/dist/core/index.js +324 -0
  19. package/dist/core/index.js.map +1 -0
  20. package/dist/crypto/index.d.ts +84 -0
  21. package/dist/crypto/index.js +144 -0
  22. package/dist/crypto/index.js.map +1 -0
  23. package/dist/date/index.d.ts +588 -0
  24. package/dist/date/index.js +737 -0
  25. package/dist/date/index.js.map +1 -0
  26. package/dist/dep-exray/analyzer/index.d.ts +7 -0
  27. package/dist/dep-exray/analyzer/index.js +68 -0
  28. package/dist/dep-exray/analyzer/index.js.map +1 -0
  29. package/dist/dep-exray/cli.d.ts +1 -0
  30. package/dist/dep-exray/cli.js +441 -0
  31. package/dist/dep-exray/cli.js.map +1 -0
  32. package/dist/dep-exray/index.d.ts +5 -0
  33. package/dist/dep-exray/index.js +454 -0
  34. package/dist/dep-exray/index.js.map +1 -0
  35. package/dist/dep-exray/known-mappings.d.ts +17 -0
  36. package/dist/dep-exray/known-mappings.js +122 -0
  37. package/dist/dep-exray/known-mappings.js.map +1 -0
  38. package/dist/dep-exray/reporter/index.d.ts +5 -0
  39. package/dist/dep-exray/reporter/index.js +89 -0
  40. package/dist/dep-exray/reporter/index.js.map +1 -0
  41. package/dist/dep-exray/scanner/index.d.ts +5 -0
  42. package/dist/dep-exray/scanner/index.js +299 -0
  43. package/dist/dep-exray/scanner/index.js.map +1 -0
  44. package/dist/dep-exray/types.d.ts +38 -0
  45. package/dist/dep-exray/types.js +1 -0
  46. package/dist/dep-exray/types.js.map +1 -0
  47. package/dist/error/index.d.ts +148 -0
  48. package/dist/error/index.js +115 -0
  49. package/dist/error/index.js.map +1 -0
  50. package/dist/index-BgG21uJC.d.ts +166 -0
  51. package/dist/index.d.ts +19 -0
  52. package/dist/index.js +4378 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/io/index.d.ts +39 -0
  55. package/dist/io/index.js +111 -0
  56. package/dist/io/index.js.map +1 -0
  57. package/dist/logger/index.d.ts +1 -0
  58. package/dist/logger/index.js +214 -0
  59. package/dist/logger/index.js.map +1 -0
  60. package/dist/logger/transports.d.ts +1 -0
  61. package/dist/logger/transports.js +122 -0
  62. package/dist/logger/transports.js.map +1 -0
  63. package/dist/math/index.d.ts +362 -0
  64. package/dist/math/index.js +372 -0
  65. package/dist/math/index.js.map +1 -0
  66. package/dist/path/index.d.ts +81 -0
  67. package/dist/path/index.js +134 -0
  68. package/dist/path/index.js.map +1 -0
  69. package/dist/string/index.d.ts +234 -0
  70. package/dist/string/index.js +411 -0
  71. package/dist/string/index.js.map +1 -0
  72. package/dist/type/index.d.ts +85 -0
  73. package/dist/type/index.js +107 -0
  74. package/dist/type/index.js.map +1 -0
  75. package/dist/validation/index.d.ts +203 -0
  76. package/dist/validation/index.js +402 -0
  77. package/dist/validation/index.js.map +1 -0
  78. package/package.json +172 -0
package/SUMMARY.md ADDED
@@ -0,0 +1,321 @@
1
+ # speedx-core — Ringkasan Fitur Lengkap
2
+
3
+ > **Versi:** 0.4.4 | **License:** MIT | **Zero runtime dependencies**
4
+
5
+ ```
6
+ npm install speedx-core
7
+ ```
8
+
9
+ ---
10
+
11
+ ## 1. CORE — Utility Functions
12
+
13
+ | Fungsi | Deskripsi |
14
+ |--------|-----------|
15
+ | `deepClone(value)` | Deep clone dengan circular reference, Date, RegExp, Map, Set support |
16
+ | `deepMerge(...objects)` | Deep merge multiple objects, nested overwrite |
17
+ | `deepEqual(a, b)` | Deep equality check — object, array, Date, Map, Set, RegExp |
18
+ | `pipe(initial, ...fns)` | Function composition left-to-right |
19
+ | `compose(...fns)` | Function composition right-to-left |
20
+ | `debounce(fn, wait, options?)` | Debounce dengan leading/trailing/maxWait |
21
+ | `throttle(fn, wait)` | Throttle execution |
22
+ | `memoize(fn, resolver?)` | Memoize dengan custom cache key |
23
+ | `retry(fn, options?)` | Retry dengan exponential backoff |
24
+ | `noop()` | No-operation function |
25
+ | `identity(value)` | Return input unchanged |
26
+ | `once(fn)` | Execute function sekali doang |
27
+
28
+ ---
29
+
30
+ ## 2. MATH
31
+
32
+ | Fungsi | Deskripsi |
33
+ |--------|-----------|
34
+ | `add(a, b)` | Safe addition (0.1+0.2=0.3) |
35
+ | `sub(a, b)` | Safe subtraction |
36
+ | `mul(a, b)` | Safe multiplication |
37
+ | `div(a, b)` | Safe division (throw kalo /0) |
38
+ | `round(value, precision?)` | Round dengan floating-point fix |
39
+ | `floor(value, precision?)` | Floor dengan precision |
40
+ | `ceil(value, precision?)` | Ceil dengan precision |
41
+ | `clamp(value, min, max)` | Clamp ke range |
42
+ | `sum(values)` | Sum of array |
43
+ | `average(values)` | Average (throw kalo kosong) |
44
+ | `randomInt(min, max)` | Random integer dalam range |
45
+ | `inRange(value, min, max)` | Cek apakah dalam range |
46
+ | `median(values)` | Median dari array |
47
+ | `stddev(values)` | Population standard deviation |
48
+ | `sampleStddev(values)` | Sample standard deviation |
49
+ | `percentile(values, p)` | Persentil (0-100) |
50
+ | `correlation(x, y)` | Pearson correlation |
51
+ | `formatCurrency(value, options?)` | Format mata uang locale-aware |
52
+
53
+ ---
54
+
55
+ ## 3. DATE & TIME
56
+
57
+ | Fungsi | Deskripsi |
58
+ |--------|-----------|
59
+ | `formatDate(date, format?)` | Format tanggal (YYYY-MM-DD, DD/MM/YYYY, dll) |
60
+ | `parseDate(input)` | Parse string/number/Date |
61
+ | `dateDiff(date1, date2)` | Selisih antar tanggal |
62
+ | `addDays(date, days)` | Tambah/kurang hari |
63
+ | `addMonths(date, months)` | Tambah/kurang bulan |
64
+ | `addYears(date, years)` | Tambah/kurang tahun |
65
+ | `startOfDay(date)` | Awal hari (00:00:00.000) |
66
+ | `endOfDay(date)` | Akhir hari (23:59:59.999) |
67
+ | `isWeekend(date)` | Sabtu atau Minggu |
68
+ | `isLeapYear(year)` | Cek tahun kabisat |
69
+ | `isBefore(date1, date2)`, `isAfter`, `isBetween` | Perbandingan tanggal |
70
+ | `isBusinessDay(date)` | Senin-Jumat |
71
+ | `addBusinessDays(date, days)` | Tambah hari kerja |
72
+ | `calculateAge(birthDate)` | Hitung umur dalam tahun |
73
+ | `timeAgo(date, options?)` | Waktu relatif ("5 detik yang lalu") |
74
+ | `timeRemaining(target, options?)` | Waktu menuju tanggal masa depan |
75
+ | `formatDuration(duration, options?)` | Format Duration object |
76
+ | `toTimezone(date, offsetHours)` | Konversi date ke timezone tertentu |
77
+ | `formatInTimezone(date, format, offset)` | Format tanggal di timezone tertentu |
78
+
79
+ ### Konstanta: `TIMEZONE_WIB` (7), `TIMEZONE_WITA` (8), `TIMEZONE_WIT` (9) 🇮🇩
80
+
81
+ ---
82
+
83
+ ## 4. COLLECTION — Array & Object Utilities
84
+
85
+ | Fungsi | Deskripsi |
86
+ |--------|-----------|
87
+ | `groupBy(items, keyFn)` | Grouping berdasarkan key |
88
+ | `keyBy(items, keyFn)` | Indexing berdasarkan key |
89
+ | `omit(obj, keys)` | Hapus keys tertentu |
90
+ | `pick(obj, keys)` | Ambil keys tertentu |
91
+ | `pluck(items, key)` | Extract property dari array |
92
+ | `shuffle(items)` | Fisher-Yates shuffle |
93
+ | `sample(items)` | Random element |
94
+ | `sampleSize(items, size)` | N random elements |
95
+ | `chunk(items, size)` | Potong array jadi chunk |
96
+ | `sortBy(items, ...criteria)` | Multi-criteria sort |
97
+ | `orderBy(items, key, dir?)` | Sort by key + direction |
98
+ | `uniqueBy(items, keyFn)` | Unique by key function |
99
+ | `flatten(items)` | Flatten satu level |
100
+ | `uniq(items)` | Hapus duplicate |
101
+ | `first(items)`, `last(items)` | Element pertama/terakhir |
102
+ | `isEmpty(value)` | Cek kosong |
103
+ | `topoSort(items)` | Topological sort (Kahn's algorithm) |
104
+ | `slidingWindows(items, size, step?)` | Overlapping windows |
105
+ | `tumblingWindows(items, size)` | Non-overlapping chunks |
106
+ | `deepGet(obj, path, default?)` | Akses nested object pake path string |
107
+ | `deepSet(obj, path, value)` | Set nested object pake path string |
108
+
109
+ ---
110
+
111
+ ## 5. STRING — Text Manipulation 🇮🇩
112
+
113
+ | Fungsi | Deskripsi |
114
+ |--------|-----------|
115
+ | `capitalize(str)` | Kapitalisasi huruf pertama |
116
+ | `camelCase(str)` | Konversi ke camelCase |
117
+ | `kebabCase(str)` | Konversi ke kebab-case |
118
+ | `snakeCase(str)` | Konversi ke snake_case |
119
+ | `pascalCase(str)` | Konversi ke PascalCase |
120
+ | `truncate(str, max, suffix?)` | Potong string dengan suffix |
121
+ | `template(str, data)` | Interpolasi string `{{key}}` |
122
+ | `uuid()` | RFC 4122 v4 UUID |
123
+ | `nanoid(size?, alphabet?)` | URL-safe random ID |
124
+ | `escapeHtml(str)` | Escape HTML entities |
125
+ | `unescapeHtml(str)` | Unescape HTML entities |
126
+ | `levenshtein(a, b)` | Levenshtein distance |
127
+ | `fuzzyMatch(str, query)` | Fuzzy string match |
128
+ | `maskString(str, options?)` | Masking data sensitif |
129
+ | `slugify(str)` | URL-friendly slug |
130
+ | `formatBytes(bytes, options?)` | Format ukuran file ("1 MB") |
131
+ | `randomString(length?)` | Random alphanumeric |
132
+ | `randomBoolean()` | Random true/false |
133
+ | `pluralize(count, singular)` | English pluralization |
134
+
135
+ ### 🇮🇩 Indonesian Locale
136
+
137
+ | Fungsi | Deskripsi |
138
+ |--------|-----------|
139
+ | `terbilang(value)` | **Angka ke kata** ("satu juta lima ratus ribu") |
140
+ | `formatRupiah(value, options?)` | **Format Rupiah** ("Rp1.500.000") |
141
+
142
+ ---
143
+
144
+ ## 6. ASYNC
145
+
146
+ | Fungsi | Deskripsi |
147
+ |--------|-----------|
148
+ | `sleep(ms)` | Delay eksekusi |
149
+ | `timeout(promise, ms)` | Reject kalo timeout |
150
+ | `raceWithTimeout(promise, ms)` | Race promise vs timeout |
151
+ | `allSettledMap(items, fn)` | Map dengan allSettled |
152
+ | `parallelMap(items, fn, concurrency?)` | Concurrent map dengan limit |
153
+ | `retryAsync(fn, options?)` | Retry dengan backoff |
154
+ | `pipeline(initial, ...fns)` | Async function composition |
155
+ | `deferred()` | Deferred promise |
156
+ | `Queue(options?)` | Priority task queue dengan concurrency |
157
+ | `Semaphore(concurrency)` | Semaphore buat resource control |
158
+ | `memoizeAsync(fn, options?)` | Async memoize dengan TTL + stale-while-revalidate |
159
+
160
+ ---
161
+
162
+ ## 7. IO
163
+
164
+ | Fungsi | Deskripsi |
165
+ |--------|-----------|
166
+ | `parseCsv(input, options?)` | Parse CSV string |
167
+ | `stringifyCsv(data, options?)` | Convert records ke CSV |
168
+ | `safeJsonParse(input, default?)` | Safe JSON parse |
169
+ | `env(name, default?)` | Baca environment variable |
170
+ | `envInt(name, default?)` | Baca env var sebagai integer |
171
+ | `envBool(name, default?)` | Baca env var sebagai boolean |
172
+
173
+ ---
174
+
175
+ ## 8. TYPE — Type Guards
176
+
177
+ | Fungsi | Deskripsi |
178
+ |--------|-----------|
179
+ | `isString`, `isNumber`, `isBoolean`, `isObject`, `isArray`, `isFunction` | Type checks |
180
+ | `isDate`, `isRegExp`, `isMap`, `isSet`, `isPromise` | Instance checks |
181
+ | `isNull`, `isUndefined`, `isNil` | Nullish checks |
182
+ | `isEmpty(value)` | Empty/blank check |
183
+ | `assertDefined(value, msg?)` | Runtime assertion |
184
+ | `assertType(value, guard, msg?)` | Type assertion |
185
+ | `ensureArray(value)` / `castArray(value)` | Wrap in array |
186
+ | `getType(value)` | String type name |
187
+
188
+ ---
189
+
190
+ ## 9. CRYPTO
191
+
192
+ | Fungsi | Deskripsi |
193
+ |--------|-----------|
194
+ | `hash(str)` | djb2 hash (32-bit) |
195
+ | `simpleHash(str)` | Simple hex hash |
196
+ | `randomHex(size?)` | Random hex string |
197
+ | `base64Encode(str)` | Base64 encode (UTF-8 safe) |
198
+ | `base64Decode(str)` | Base64 decode |
199
+ | `generateToken(bytes?)` | Crypto-random hex token |
200
+ | `generateOTP(length?)` | Numeric OTP |
201
+ | `xorCipher(str, key)` | ⚠️ XOR obfuscation (BUKAN encryption) |
202
+ | `checksum(input)` | CRC-like checksum |
203
+ | `constantTimeEqual(a, b)` | Timing-safe string comparison |
204
+
205
+ ---
206
+
207
+ ## 10. PATH
208
+
209
+ | Fungsi | Deskripsi |
210
+ |--------|-----------|
211
+ | `join(...segments)` | Gabung path segments |
212
+ | `resolve(...segments)` | Resolve ke absolute path |
213
+ | `basename(p, ext?)` | Ambil filename |
214
+ | `dirname(p)` | Ambil directory |
215
+ | `extname(p)` | Ambil extension |
216
+ | `normalize(p)` | Normalize path |
217
+ | `isAbsolute(p)` | Cek absolute path |
218
+ | `relative(from, to)` | Relative path |
219
+ | `parse(p)` | Parse path jadi components |
220
+ | `format(parsed)` | Format parsed path |
221
+
222
+ ---
223
+
224
+ ## 11. VALIDATION — 🇮🇩 Khusus Indonesia
225
+
226
+ | Fungsi | Deskripsi |
227
+ |--------|-----------|
228
+ | `isNIK(value)` | **Validasi NIK** 16 digit + tanggal lahir |
229
+ | `parseNIK(value)` | **Extract data dari NIK** — gender, provinsi, tanggal lahir |
230
+ | `isNPWP(value)` | **Validasi NPWP** + checksum |
231
+ | `isPlatNomor(value)` | **Validasi plat kendaraan** RI (B 1234 CD) |
232
+ | `isPhone(value, country?)` | **Validasi nomor HP Indonesia** |
233
+ | `isKodepos(value)` | **Validasi kode pos** 5 digit |
234
+ | `isNoRekening(value)` | **Validasi nomor rekening** bank (8-16 digit) |
235
+ | `isEmail(value)` | Validasi email RFC-compliant |
236
+ | `isURL(value)` | Validasi URL (http/https) |
237
+
238
+ ---
239
+
240
+ ## 12. ERROR — Typed Errors
241
+
242
+ | Fungsi | Deskripsi |
243
+ |--------|-----------|
244
+ | `createError(code, message, options?)` | Bikin typed error dengan HTTP status |
245
+ | `isTypedError(error)` | Type guard |
246
+ | `TypedError` | Class dengan code + status + details + toJSON |
247
+ | `MultiError` | Kumpulin multiple errors |
248
+ | `collectErrors(fn)` | Jalanin function, kumpulin error yang ke-throw |
249
+
250
+ ### Error Codes: `BAD_REQUEST` (400), `UNAUTHORIZED` (401), `FORBIDDEN` (403), `NOT_FOUND` (404), `CONFLICT` (409), `VALIDATION_ERROR` (422), `TOO_MANY` (429), `INTERNAL` (500), `BAD_GATEWAY` (502), `UNAVAILABLE` (503)
251
+
252
+ ---
253
+
254
+ ## 13. LOGGER — Structured Logging
255
+
256
+ | Fungsi | Deskripsi |
257
+ |--------|-----------|
258
+ | `Logger(options?)` | Structured logger dengan level |
259
+ | `logger` | Default singleton (info level) |
260
+ | `createConsoleTransport(options?)` | Colored console output |
261
+ | `createJsonTransport(options?)` | JSON-line output |
262
+ | `createFileTransport(filename, options?)` | File appender |
263
+ | `createBufferedTransport(transport, options?)` | Batched transport |
264
+
265
+ ### Log Levels: `debug`, `info`, `warn`, `error`
266
+
267
+ ---
268
+
269
+ ## 14. COLOR — Color Utilities
270
+
271
+ | Fungsi | Deskripsi |
272
+ |--------|-----------|
273
+ | `hexToRgb(hex)` | Convert hex ke RGB object |
274
+ | `rgbToHex(r, g, b)` | Convert RGB ke hex string |
275
+ | `lighten(hex, percent)` | Terangin warna (0-100%) |
276
+ | `darken(hex, percent)` | Gelapin warna (0-100%) |
277
+ | `contrastRatio(hex1, hex2)` | WCAG contrast ratio (1-21) |
278
+ | `meetsWCAG(hex1, hex2, level?)` | Cek WCAG compliance (AA/AAA) |
279
+
280
+ ---
281
+
282
+ ## 15. DEP-EXRAY — Dependency Health Scanner
283
+
284
+ | Fungsi | Deskripsi |
285
+ |--------|-----------|
286
+ | `scanProject(config)` | Scan project buat bloat + security issues |
287
+ | `generateReport(result, json?)` | Generate scan report |
288
+ | `analyzeUsage(projectPath, packageName)` | Deteksi pemakaian dependency |
289
+ | `KNOWN_MAPPINGS` | 11 known replacement mappings |
290
+ | `KNOWN_CVES` | CVE database untuk known packages |
291
+
292
+ **CLI:** `npx dep-exray .`
293
+
294
+ ---
295
+
296
+ ## Statistik Test
297
+
298
+ | Module | Test Files | Tests |
299
+ |--------|-----------|-------|
300
+ | Semua module | 19 | **828** ✅ |
301
+
302
+ ---
303
+
304
+ ## Referensi Cepat
305
+
306
+ ```bash
307
+ npm install speedx-core
308
+
309
+ # Import semua module
310
+ import { deepClone, deepEqual, pipe } from 'speedx-core'
311
+ import { formatDate, timeAgo, TIMEZONE_WIB } from 'speedx-core/date'
312
+ import { groupBy, topoSort, deepGet } from 'speedx-core/collection'
313
+ import { terbilang, formatRupiah, formatBytes } from 'speedx-core/string'
314
+ import { Queue, Semaphore } from 'speedx-core/async'
315
+ import { isNIK, isNPWP, isPhone } from 'speedx-core/validation'
316
+ import { createError, MultiError } from 'speedx-core/error'
317
+ import { Logger } from 'speedx-core/logger'
318
+ import { hexToRgb, lighten, contrastRatio } from 'speedx-core/color'
319
+ import { median, stddev, formatCurrency } from 'speedx-core/math'
320
+ import { scanProject } from 'speedx-core/dep-exray'
321
+ ```
@@ -0,0 +1,232 @@
1
+ import { RetryOptions } from '../core/index.js';
2
+
3
+ interface QueueOptions {
4
+ concurrency?: number;
5
+ }
6
+ /**
7
+ * Priority-based async task queue with concurrency control.
8
+ *
9
+ * @example
10
+ * const queue = new Queue({ concurrency: 2 })
11
+ * const result = await queue.add(() => fetch('/api/data'))
12
+ */
13
+ declare class Queue<T = unknown> {
14
+ private _tasks;
15
+ private _running;
16
+ private _paused;
17
+ private _idleResolve;
18
+ private _maxConcurrency;
19
+ constructor(options?: QueueOptions);
20
+ get pending(): number;
21
+ get running(): number;
22
+ add<R>(task: () => Promise<R>, options?: {
23
+ priority?: number;
24
+ }): Promise<R>;
25
+ pause(): void;
26
+ resume(): void;
27
+ clear(): void;
28
+ onIdle(): Promise<void>;
29
+ private _process;
30
+ }
31
+
32
+ /**
33
+ * Semaphore for controlling concurrent access to a resource.
34
+ *
35
+ * @example
36
+ * const sem = new Semaphore(2)
37
+ * await sem.use(async () => {
38
+ * // Only 2 callers at a time
39
+ * await doSomething()
40
+ * })
41
+ */
42
+ declare class Semaphore {
43
+ private _available;
44
+ private _waiting;
45
+ constructor(concurrency: number);
46
+ get available(): number;
47
+ acquire(): Promise<() => void>;
48
+ use<T>(fn: () => Promise<T>): Promise<T>;
49
+ private _release;
50
+ }
51
+
52
+ /**
53
+ * Options for memoizeAsync.
54
+ */
55
+ interface MemoizeAsyncOptions {
56
+ /** Time-to-live in milliseconds (default: 60000) */
57
+ ttl?: number;
58
+ /** Return stale value while fetching fresh data (default: false) */
59
+ staleWhileRevalidate?: boolean;
60
+ /** Maximum number of cached entries (default: 100) */
61
+ maxSize?: number;
62
+ /** Custom cache key resolver. Defaults to JSON.stringify of args. */
63
+ resolver?: (...args: unknown[]) => string;
64
+ }
65
+ interface CacheEntry {
66
+ value: unknown;
67
+ timestamp: number;
68
+ promise?: Promise<unknown>;
69
+ }
70
+ /**
71
+ * Memoizes an async function with TTL, stale-while-revalidate, and bounded cache.
72
+ *
73
+ * @example
74
+ * const fetchData = memoizeAsync(async (id: string) => {
75
+ * return await api.fetch(id)
76
+ * }, { ttl: 5000, staleWhileRevalidate: true })
77
+ *
78
+ * const data = await fetchData('123') // cached for 5s
79
+ * const data2 = await fetchData('123') // returns cached, refreshes in bg
80
+ */
81
+ declare function memoizeAsync<T extends (...args: unknown[]) => Promise<unknown>>(fn: T, options?: MemoizeAsyncOptions): T & {
82
+ cache: Map<string, CacheEntry>;
83
+ clear: () => void;
84
+ };
85
+
86
+ /**
87
+ * Rate limiter that restricts the number of requests within a sliding time window.
88
+ *
89
+ * @example
90
+ * const limiter = new RateLimiter({ maxRequests: 5, perWindow: 1000 })
91
+ * if (limiter.tryAcquire()) {
92
+ * // Allowed
93
+ * }
94
+ *
95
+ * @example
96
+ * const limiter = new RateLimiter({ maxRequests: 2, perWindow: 1000 })
97
+ * await limiter.acquire()
98
+ * await limiter.acquire()
99
+ * // Third call waits until the window rolls
100
+ */
101
+ declare class RateLimiter {
102
+ private _maxRequests;
103
+ private _perWindow;
104
+ private _timestamps;
105
+ constructor(options: {
106
+ maxRequests: number;
107
+ perWindow: number;
108
+ });
109
+ private _prune;
110
+ /**
111
+ * Check if a request is allowed without waiting.
112
+ */
113
+ tryAcquire(): boolean;
114
+ /**
115
+ * Wait until a request is allowed.
116
+ */
117
+ acquire(): Promise<void>;
118
+ /**
119
+ * Current number of pending requests in the window.
120
+ */
121
+ get pending(): number;
122
+ }
123
+
124
+ /**
125
+ * Mutex for exclusive access to a critical section.
126
+ *
127
+ * @example
128
+ * const mutex = new Mutex()
129
+ * const release = await mutex.acquire()
130
+ * try {
131
+ * // Exclusive access
132
+ * } finally {
133
+ * release()
134
+ * }
135
+ *
136
+ * @example
137
+ * const mutex = new Mutex()
138
+ * const result = await mutex.use(async () => {
139
+ * return await fetch('/api/data')
140
+ * })
141
+ */
142
+ declare class Mutex {
143
+ private _locked;
144
+ private _waiting;
145
+ /**
146
+ * Acquire the lock. Returns a release function to be called when done.
147
+ */
148
+ acquire(): Promise<() => void>;
149
+ /**
150
+ * Run a function with the lock held and automatically release it.
151
+ */
152
+ use<T>(fn: () => Promise<T>): Promise<T>;
153
+ /**
154
+ * Whether the mutex is currently locked.
155
+ */
156
+ get locked(): boolean;
157
+ private _release;
158
+ }
159
+
160
+ /**
161
+ * Process an array of items in sequential batches.
162
+ *
163
+ * @example
164
+ * const items = [1, 2, 3, 4, 5]
165
+ * const results = await batch(items, 2, async (batch) => {
166
+ * return batch.map(n => n * 2)
167
+ * })
168
+ * // results = [2, 4, 6, 8, 10]
169
+ */
170
+ declare function batch<T, R>(items: T[], batchSize: number, fn: (batch: T[]) => Promise<R[]>): Promise<R[]>;
171
+
172
+ /**
173
+ * Execute async tasks in sequence, passing each result to the next task.
174
+ *
175
+ * @example
176
+ * const result = await waterfall([
177
+ * async (n: number) => n + 1,
178
+ * async (n: number) => n * 2,
179
+ * async (n: number) => `Result: ${n}`,
180
+ * ], 1)
181
+ * // result = "Result: 4"
182
+ *
183
+ * @example
184
+ * const result = await waterfall([
185
+ * async () => fetch('/api/data').then(r => r.json()),
186
+ * async (data) => process(data),
187
+ * ])
188
+ */
189
+ declare function waterfall(tasks: Array<(arg: any) => Promise<any>>, initial?: any): Promise<any>;
190
+
191
+ /**
192
+ * Delays execution for the given number of milliseconds.
193
+ */
194
+ declare function sleep(ms: number): Promise<void>;
195
+ /**
196
+ * Rejects a promise if it does not resolve within the specified timeout.
197
+ */
198
+ declare function timeout<T>(promise: Promise<T>, ms: number, errorMessage?: string): Promise<T>;
199
+ /**
200
+ * Races a promise against a timeout, returning 'timeout' if the timer wins.
201
+ */
202
+ declare function raceWithTimeout<T>(promise: Promise<T>, ms: number): Promise<T | 'timeout'>;
203
+ /**
204
+ * Maps over an array with an async function, using Promise.allSettled.
205
+ * Returns an array of PromiseSettledResult.
206
+ */
207
+ declare function allSettledMap<T, R>(items: T[], fn: (item: T) => Promise<R>): Promise<PromiseSettledResult<R>[]>;
208
+ /**
209
+ * Maps over an array with an async function, limiting concurrency.
210
+ *
211
+ * @param concurrency - Maximum number of concurrent operations (default Infinity)
212
+ */
213
+ declare function parallelMap<T, R>(items: T[], fn: (item: T) => Promise<R>, concurrency?: number): Promise<R[]>;
214
+ /**
215
+ * Retries an async function with exponential backoff.
216
+ */
217
+ declare function retryAsync<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
218
+ /**
219
+ * Composes async functions, passing the result of each to the next.
220
+ */
221
+ declare function pipeline<T>(initial: T, ...fns: Array<(arg: T) => Promise<T>>): Promise<T>;
222
+ /**
223
+ * Creates a deferred promise with external resolve and reject methods.
224
+ */
225
+ declare function deferred<T>(): Deferred<T>;
226
+ interface Deferred<T> {
227
+ promise: Promise<T>;
228
+ resolve: (value: T) => void;
229
+ reject: (reason: unknown) => void;
230
+ }
231
+
232
+ export { type Deferred, type MemoizeAsyncOptions, Mutex, Queue, type QueueOptions, RateLimiter, Semaphore, allSettledMap, batch, deferred, memoizeAsync, parallelMap, pipeline, raceWithTimeout, retryAsync, sleep, timeout, waterfall };