@satoshibits/functional 1.0.2

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 (46) hide show
  1. package/README.md +242 -0
  2. package/dist/array-utils.d.mts +317 -0
  3. package/dist/array-utils.d.mts.map +1 -0
  4. package/dist/array-utils.mjs +370 -0
  5. package/dist/array-utils.mjs.map +1 -0
  6. package/dist/composition.d.mts +603 -0
  7. package/dist/composition.d.mts.map +1 -0
  8. package/dist/composition.mjs +516 -0
  9. package/dist/composition.mjs.map +1 -0
  10. package/dist/object-utils.d.mts +267 -0
  11. package/dist/object-utils.d.mts.map +1 -0
  12. package/dist/object-utils.mjs +258 -0
  13. package/dist/object-utils.mjs.map +1 -0
  14. package/dist/option.d.mts +622 -0
  15. package/dist/option.d.mts.map +1 -0
  16. package/dist/option.mjs +637 -0
  17. package/dist/option.mjs.map +1 -0
  18. package/dist/performance.d.mts +265 -0
  19. package/dist/performance.d.mts.map +1 -0
  20. package/dist/performance.mjs +453 -0
  21. package/dist/performance.mjs.map +1 -0
  22. package/dist/pipeline.d.mts +431 -0
  23. package/dist/pipeline.d.mts.map +1 -0
  24. package/dist/pipeline.mjs +460 -0
  25. package/dist/pipeline.mjs.map +1 -0
  26. package/dist/predicates.d.mts +722 -0
  27. package/dist/predicates.d.mts.map +1 -0
  28. package/dist/predicates.mjs +802 -0
  29. package/dist/predicates.mjs.map +1 -0
  30. package/dist/reader-result.d.mts +422 -0
  31. package/dist/reader-result.d.mts.map +1 -0
  32. package/dist/reader-result.mjs +758 -0
  33. package/dist/reader-result.mjs.map +1 -0
  34. package/dist/result.d.mts +684 -0
  35. package/dist/result.d.mts.map +1 -0
  36. package/dist/result.mjs +814 -0
  37. package/dist/result.mjs.map +1 -0
  38. package/dist/types.d.mts +439 -0
  39. package/dist/types.d.mts.map +1 -0
  40. package/dist/types.mjs +191 -0
  41. package/dist/types.mjs.map +1 -0
  42. package/dist/validation.d.mts +622 -0
  43. package/dist/validation.d.mts.map +1 -0
  44. package/dist/validation.mjs +852 -0
  45. package/dist/validation.mjs.map +1 -0
  46. package/package.json +46 -0
@@ -0,0 +1,603 @@
1
+ /**
2
+ * @module composition
3
+ * @description Core functional composition utilities using TypeScript 4.0+ variadic tuple types.
4
+ * Provides type-safe function composition with automatic type inference
5
+ * for pipelines of any length. All functions follow functional programming principles,
6
+ * supporting both synchronous and asynchronous composition patterns.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { pipe, flow, compose, tap, pipeAsync } from './composition.mts';
11
+ *
12
+ * // pipe - execute functions with an initial value
13
+ * const result = pipe(
14
+ * 5,
15
+ * x => x * 2,
16
+ * x => x + 1,
17
+ * x => `Result: ${x}`
18
+ * );
19
+ * // => "Result: 11"
20
+ *
21
+ * // flow - create reusable pipelines
22
+ * const processUser = flow(
23
+ * (user: User) => ({ ...user, name: user.name.trim() }),
24
+ * user => ({ ...user, name: user.name.toUpperCase() }),
25
+ * user => ({ ...user, isActive: true })
26
+ * );
27
+ *
28
+ * // compose - right-to-left composition
29
+ * const calculate = compose(
30
+ * Math.round,
31
+ * Math.sqrt,
32
+ * Math.abs
33
+ * );
34
+ *
35
+ * // async composition
36
+ * const fetchAndProcess = pipeAsync(
37
+ * async (id: string) => fetchUser(id),
38
+ * async (user: User) => enrichUser(user),
39
+ * async (enriched: EnrichedUser) => saveUser(enriched)
40
+ * );
41
+ * ```
42
+ *
43
+ * @category Core
44
+ * @since 2025-07-03
45
+ */
46
+ /**
47
+ * Pipe - applies a series of functions from left to right.
48
+ * @description Executes a sequence of functions in order, passing the result of each function
49
+ * as the argument to the next. The first argument is the initial value, followed by functions
50
+ * that transform the value step by step. Supports up to 6 transformations with full type inference.
51
+ *
52
+ * @template A - Type of the initial value
53
+ * @template B,C,D,E,F,G - Types of intermediate and final values through the pipeline
54
+ * @param {A} value - The initial value to transform
55
+ * @param {...Function} fns - Functions to apply in sequence
56
+ * @returns {*} The final transformed value
57
+ *
58
+ * @category Core
59
+ * @example
60
+ * // Basic transformation pipeline
61
+ * const result = pipe(
62
+ * 5,
63
+ * x => x * 2,
64
+ * x => x + 1,
65
+ * x => `Result: ${x}`
66
+ * );
67
+ * // => "Result: 11"
68
+ *
69
+ * @example
70
+ * // Complex data transformation
71
+ * const user = { name: 'john', age: 25 };
72
+ * const formatted = pipe(
73
+ * user,
74
+ * u => ({ ...u, name: u.name.toUpperCase() }),
75
+ * u => ({ ...u, ageGroup: u.age >= 18 ? 'adult' : 'minor' }),
76
+ * u => `${u.name} (${u.ageGroup})`
77
+ * );
78
+ * // => "JOHN (adult)"
79
+ *
80
+ * @example
81
+ * // Working with arrays
82
+ * const doubled = pipe(
83
+ * [1, 2, 3, 4, 5],
84
+ * arr => arr.map(x => x * 2),
85
+ * arr => arr.filter(x => x > 5),
86
+ * arr => arr.reduce((sum, x) => sum + x, 0)
87
+ * );
88
+ * // => 18 (6 + 8 + 10)
89
+ *
90
+ * @see flow - Create a reusable pipeline function
91
+ * @see compose - Right-to-left composition
92
+ * @since 2025-07-03
93
+ */
94
+ export declare function pipe<A>(value: A): A;
95
+ export declare function pipe<A, B>(value: A, fn1: (a: A) => B): B;
96
+ export declare function pipe<A, B, C>(value: A, fn1: (a: A) => B, fn2: (b: B) => C): C;
97
+ export declare function pipe<A, B, C, D>(value: A, fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D): D;
98
+ export declare function pipe<A, B, C, D, E>(value: A, fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E): E;
99
+ export declare function pipe<A, B, C, D, E, F>(value: A, fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F): F;
100
+ export declare function pipe<A, B, C, D, E, F, G>(value: A, fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F, fn6: (f: F) => G): G;
101
+ /**
102
+ * Flow - compose functions without an initial value.
103
+ * Creates a reusable pipeline function that can be called multiple times
104
+ * with different inputs.
105
+ *
106
+ * @category Core
107
+ * @example
108
+ * // Create a reusable pipeline
109
+ * const processUser = flow(
110
+ * (user: { name: string; age: number }) => ({ ...user, name: user.name.trim() }),
111
+ * user => ({ ...user, name: user.name.toUpperCase() }),
112
+ * user => ({ ...user, isAdult: user.age >= 18 })
113
+ * );
114
+ *
115
+ * processUser({ name: ' john ', age: 25 });
116
+ * // => { name: 'JOHN', age: 25, isAdult: true }
117
+ *
118
+ * @example
119
+ * // String processing pipeline
120
+ * const slugify = flow(
121
+ * (str: string) => str.toLowerCase(),
122
+ * str => str.trim(),
123
+ * str => str.replace(/\s+/g, '-'),
124
+ * str => str.replace(/[^a-z0-9-]/g, '')
125
+ * );
126
+ *
127
+ * slugify('Hello World!'); // => 'hello-world'
128
+ * slugify(' TypeScript 4.0 '); // => 'typescript-40'
129
+ *
130
+ * @example
131
+ * // Data validation pipeline
132
+ * const validateAndTransform = flow(
133
+ * (data: unknown) => data as { name?: string; email?: string },
134
+ * data => {
135
+ * if (!data.name) throw new Error('Name is required');
136
+ * if (!data.email) throw new Error('Email is required');
137
+ * return data as { name: string; email: string };
138
+ * },
139
+ * data => ({
140
+ * ...data,
141
+ * name: data.name.trim(),
142
+ * email: data.email.toLowerCase()
143
+ * })
144
+ * );
145
+ *
146
+ * @see pipe - Apply functions with an initial value
147
+ * @see compose - Right-to-left composition
148
+ */
149
+ export declare function flow<A, B>(fn1: (a: A) => B): (a: A) => B;
150
+ export declare function flow<A, B, C>(fn1: (a: A) => B, fn2: (b: B) => C): (a: A) => C;
151
+ export declare function flow<A, B, C, D>(fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D): (a: A) => D;
152
+ export declare function flow<A, B, C, D, E>(fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E): (a: A) => E;
153
+ export declare function flow<A, B, C, D, E, F>(fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D, fn4: (d: D) => E, fn5: (e: E) => F): (a: A) => F;
154
+ export declare function flow<Args extends unknown[], B>(fn1: (...args: Args) => B): (...args: Args) => B;
155
+ export declare function flow<Args extends unknown[], B, C>(fn1: (...args: Args) => B, fn2: (b: B) => C): (...args: Args) => C;
156
+ export declare function flow<Args extends unknown[], B, C, D>(fn1: (...args: Args) => B, fn2: (b: B) => C, fn3: (c: C) => D): (...args: Args) => D;
157
+ /**
158
+ * Identity function - returns its input unchanged.
159
+ * @description A function that returns its argument without any modification.
160
+ * Useful as a default or placeholder in pipelines, for filtering truthy values,
161
+ * or when conditional transformations are needed.
162
+ *
163
+ * @template T - The type of the input and output
164
+ * @param {T} x - The value to return unchanged
165
+ * @returns {T} The same value that was passed in
166
+ *
167
+ * @category Utilities
168
+ * @example
169
+ * // As a default transformation
170
+ * const transform = shouldTransform ? (x: number) => x * 2 : identity;
171
+ * [1, 2, 3].map(transform); // => [1, 2, 3] or [2, 4, 6]
172
+ *
173
+ * @example
174
+ * // Filtering out falsy values while preserving types
175
+ * const values = [1, null, 2, undefined, 3];
176
+ * const nonNull = values.filter(identity); // => [1, 2, 3]
177
+ *
178
+ * @example
179
+ * // As a placeholder in conditional pipelines
180
+ * const pipeline = flow(
181
+ * validateInput,
182
+ * shouldNormalize ? normalizeData : identity,
183
+ * saveToDatabase
184
+ * );
185
+ *
186
+ * @see constant - Create a function that always returns the same value
187
+ * @since 2025-07-03
188
+ */
189
+ export declare const identity: <T>(x: T) => T;
190
+ /**
191
+ * Constant function - creates a function that always returns the same value.
192
+ * @description Returns a function that ignores its arguments and always returns the specified value.
193
+ * Useful for providing default values, mocking in tests, or replacing complex logic with fixed results.
194
+ *
195
+ * @template T - The type of the constant value
196
+ * @param {T} x - The value to always return
197
+ * @returns {() => T} A function that always returns the constant value
198
+ *
199
+ * @category Utilities
200
+ * @example
201
+ * // Default value provider
202
+ * const getDefault = constant({ status: 'pending', count: 0 });
203
+ * const status = userStatus || getDefault();
204
+ *
205
+ * @example
206
+ * // Mock functions in tests
207
+ * const mockUserService = {
208
+ * getCurrentUser: constant({ id: 1, name: 'Test User' }),
209
+ * isAuthenticated: constant(true)
210
+ * };
211
+ *
212
+ * @example
213
+ * // Replacing conditional logic
214
+ * const getDiscount = isPremium
215
+ * ? calculatePremiumDiscount
216
+ * : constant(0);
217
+ *
218
+ * @see identity - Return the input unchanged
219
+ * @since 2025-07-03
220
+ */
221
+ export declare const constant: <T>(x: T) => () => T;
222
+ /**
223
+ * Compose - right-to-left function composition (opposite of flow).
224
+ * For those who prefer mathematical composition order where (f ∘ g)(x) = f(g(x)).
225
+ *
226
+ * @category Core
227
+ * @example
228
+ * // Mathematical style composition
229
+ * const addThenDouble = compose(
230
+ * (x: number) => x * 2, // second
231
+ * (x: number) => x + 1 // first
232
+ * );
233
+ * addThenDouble(5); // => 12 ((5 + 1) * 2)
234
+ *
235
+ * @example
236
+ * // Reading right-to-left
237
+ * const processData = compose(
238
+ * JSON.stringify, // 3. Convert to JSON
239
+ * addTimestamp, // 2. Add metadata
240
+ * validateData // 1. Validate first
241
+ * );
242
+ *
243
+ * @example
244
+ * // Equivalent to nested function calls
245
+ * const traditional = (x: number) => Math.round(Math.sqrt(Math.abs(x)));
246
+ * const composed = compose(Math.round, Math.sqrt, Math.abs);
247
+ * // Both produce the same result
248
+ *
249
+ * @see flow - Left-to-right composition
250
+ * @see pipe - Apply functions with an initial value
251
+ */
252
+ export declare function compose<A, B>(fn1: (a: A) => B): (a: A) => B;
253
+ export declare function compose<A, B, C>(fn2: (b: B) => C, fn1: (a: A) => B): (a: A) => C;
254
+ export declare function compose<A, B, C, D>(fn3: (c: C) => D, fn2: (b: B) => C, fn1: (a: A) => B): (a: A) => D;
255
+ export declare function compose<A, B, C, D, E>(fn4: (d: D) => E, fn3: (c: C) => D, fn2: (b: B) => C, fn1: (a: A) => B): (a: A) => E;
256
+ export declare function compose<Args extends unknown[], B>(fn1: (...args: Args) => B): (...args: Args) => B;
257
+ export declare function compose<Args extends unknown[], B, C>(fn2: (b: B) => C, fn1: (...args: Args) => B): (...args: Args) => C;
258
+ export declare function compose<Args extends unknown[], B, C, D>(fn3: (c: C) => D, fn2: (b: B) => C, fn1: (...args: Args) => B): (...args: Args) => D;
259
+ /**
260
+ * Tap - execute a side effect without changing the value.
261
+ * @description Executes a function for its side effects while passing the input value through unchanged.
262
+ * Useful for debugging, logging, or triggering external actions in pipelines without breaking the flow.
263
+ * The side effect function receives the value but its return value is ignored.
264
+ *
265
+ * @template T - The type of the value being passed through
266
+ * @param {function(T): void} fn - Function to execute for side effects
267
+ * @returns {function(T): T} A function that executes the side effect and returns the input
268
+ *
269
+ * @category Side Effects
270
+ * @example
271
+ * // Debugging pipeline steps
272
+ * const result = pipe(
273
+ * { name: 'John', age: 30 },
274
+ * tap(console.log), // Log initial value
275
+ * user => ({ ...user, age: user.age + 1 }),
276
+ * tap(user => console.log('After increment:', user)),
277
+ * user => ({ ...user, status: 'active' })
278
+ * );
279
+ *
280
+ * @example
281
+ * // Triggering side effects
282
+ * const saveUser = pipe(
283
+ * validateUser,
284
+ * tap(user => analytics.track('user_validated', { id: user.id })),
285
+ * normalizeUser,
286
+ * tap(user => cache.set(user.id, user)),
287
+ * saveToDatabase
288
+ * );
289
+ *
290
+ * @example
291
+ * // Conditional debugging
292
+ * const debug = process.env.DEBUG === 'true';
293
+ * const pipeline = flow(
294
+ * parseData,
295
+ * debug ? tap(data => console.log('Parsed:', data)) : identity,
296
+ * transformData
297
+ * );
298
+ *
299
+ * @see identity - Pass through without side effects
300
+ * @since 2025-07-03
301
+ */
302
+ export declare const tap: <T>(fn: (x: T) => void) => (x: T) => T;
303
+ /**
304
+ * Currying utility - converts a function of multiple arguments into a sequence of functions.
305
+ * Each function takes a single argument and returns another function until all arguments are provided.
306
+ *
307
+ * @category Function Transformation
308
+ * @example
309
+ * // Basic currying
310
+ * const add = (a: number, b: number) => a + b;
311
+ * const curriedAdd = curry(add);
312
+ * const add5 = curriedAdd(5);
313
+ * add5(3); // => 8
314
+ *
315
+ * @example
316
+ * // Building reusable functions
317
+ * const multiply = curry((factor: number, value: number) => value * factor);
318
+ * const double = multiply(2);
319
+ * const triple = multiply(3);
320
+ *
321
+ * [1, 2, 3].map(double); // => [2, 4, 6]
322
+ * [1, 2, 3].map(triple); // => [3, 6, 9]
323
+ *
324
+ * @example
325
+ * // Configuration functions
326
+ * const createLogger = curry((level: string, category: string, message: string) =>
327
+ * console.log(`[${level}] ${category}: ${message}`)
328
+ * );
329
+ *
330
+ * const errorLogger = createLogger('ERROR');
331
+ * const authErrorLogger = errorLogger('AUTH');
332
+ * authErrorLogger('Invalid credentials'); // => "[ERROR] AUTH: Invalid credentials"
333
+ *
334
+ * @see partial - Fix some arguments of a function
335
+ * @see flip - Reverse argument order
336
+ */
337
+ export declare const curry: <A, B, C>(fn: (a: A, b: B) => C) => (a: A) => (b: B) => C;
338
+ /**
339
+ * Partial application - fixes some arguments of a function.
340
+ * Returns a new function that takes the remaining arguments.
341
+ *
342
+ * @category Function Transformation
343
+ * @example
344
+ * // Partially apply configuration
345
+ * const greet = (greeting: string, name: string) => `${greeting}, ${name}!`;
346
+ * const sayHello = partial(greet, 'Hello');
347
+ * sayHello('World'); // => "Hello, World!"
348
+ *
349
+ * @example
350
+ * // Creating specialized functions
351
+ * const fetchAPI = (method: string, endpoint: string, body?: unknown) =>
352
+ * fetch(endpoint, { method, body: JSON.stringify(body) });
353
+ *
354
+ * const postAPI = partial(fetchAPI, 'POST');
355
+ * const getAPI = partial(fetchAPI, 'GET');
356
+ *
357
+ * postAPI('/users', { name: 'John' });
358
+ * getAPI('/users');
359
+ *
360
+ * @example
361
+ * // Event handler specialization
362
+ * const logEvent = (category: string, action: string, label: string) =>
363
+ * analytics.track({ category, action, label });
364
+ *
365
+ * const logUserAction = partial(logEvent, 'USER');
366
+ * const logButtonClick = partial(logUserAction, 'CLICK');
367
+ *
368
+ * logButtonClick('submit-form'); // Logs: { category: 'USER', action: 'CLICK', label: 'submit-form' }
369
+ *
370
+ * @see curry - Convert to single-argument functions
371
+ * @see flip - Reverse argument order
372
+ */
373
+ export declare const partial: <A extends unknown[], B, C>(fn: (...args: [...A, B]) => C, ...args: A) => (lastArg: B) => C;
374
+ /**
375
+ * Flip - reverses the order of arguments for a binary function.
376
+ * Useful when you need to adapt a function to work with different argument orders.
377
+ *
378
+ * @category Function Transformation
379
+ * @example
380
+ * // Basic flip
381
+ * const divide = (a: number, b: number) => a / b;
382
+ * const divideBy = flip(divide);
383
+ * divideBy(2, 10); // => 5 (10 / 2)
384
+ *
385
+ * @example
386
+ * // Adapting functions for composition
387
+ * const concat = (a: string, b: string) => a + b;
388
+ * const prepend = flip(concat);
389
+ *
390
+ * const addPrefix = prepend('PREFIX_');
391
+ * addPrefix('value'); // => "valuePREFIX_"
392
+ *
393
+ * @example
394
+ * // Working with collections
395
+ * const has = (obj: Record<string, unknown>, key: string) => key in obj;
396
+ * const hasKey = flip(has);
397
+ *
398
+ * const users = [{ name: 'John' }, { name: 'Jane', admin: true }];
399
+ * users.filter(hasKey('admin')); // => [{ name: 'Jane', admin: true }]
400
+ *
401
+ * @see curry - Convert to single-argument functions
402
+ * @see partial - Fix some arguments
403
+ */
404
+ export declare const flip: <A, B, C>(fn: (a: A, b: B) => C) => (b: B, a: A) => C;
405
+ /**
406
+ * Memoization - caches function results based on arguments.
407
+ * Improves performance for expensive pure functions by storing previously computed results.
408
+ *
409
+ * @category Performance
410
+ * @example
411
+ * // Memoize expensive calculations
412
+ * const fibonacci = memoize((n: number): number => {
413
+ * if (n <= 1) return n;
414
+ * return fibonacci(n - 1) + fibonacci(n - 2);
415
+ * });
416
+ *
417
+ * fibonacci(40); // First call: slow
418
+ * fibonacci(40); // Second call: instant (cached)
419
+ *
420
+ * @example
421
+ * // Custom cache key generation
422
+ * const processUser = memoize(
423
+ * async (userId: string, options: { includeDetails: boolean }) => {
424
+ * const user = await fetchUser(userId);
425
+ * return options.includeDetails
426
+ * ? { ...user, details: await fetchUserDetails(userId) }
427
+ * : user;
428
+ * },
429
+ * (userId, options) => `${userId}-${options.includeDetails}`
430
+ * );
431
+ *
432
+ * @example
433
+ * // Memoizing API calls
434
+ * const fetchProductData = memoize(async (productId: string) => {
435
+ * const response = await fetch(`/api/products/${productId}`);
436
+ * return response.json();
437
+ * });
438
+ *
439
+ * // Multiple components can call this without duplicate requests
440
+ * await fetchProductData('123'); // Makes API call
441
+ * await fetchProductData('123'); // Returns cached result
442
+ *
443
+ * @see identity - For functions that don't need memoization
444
+ */
445
+ export declare const memoize: <Args extends unknown[], Return>(fn: (...args: Args) => Return, getKey?: (...args: Args) => string) => ((...args: Args) => Return);
446
+ /**
447
+ * Compose async functions from right to left.
448
+ * Allows composition of Promise-returning functions in mathematical order.
449
+ * Now supports any number of async functions.
450
+ *
451
+ * @category Async
452
+ * @example
453
+ * // Async data processing pipeline
454
+ * const processData = composeAsync(
455
+ * async (data: ProcessedData) => saveToDatabase(data), // 3. Save
456
+ * async (data: ValidatedData) => transformData(data), // 2. Transform
457
+ * async (data: RawData) => validateData(data) // 1. Validate
458
+ * );
459
+ *
460
+ * const result = await processData(rawData);
461
+ *
462
+ * @example
463
+ * // API call composition with multiple steps
464
+ * const fetchUserWithPosts = composeAsync(
465
+ * async (enriched: EnrichedUser) => logActivity(enriched), // 5. Log
466
+ * async (userData: UserWithMetadata) => enrichWithMetadata(userData),// 4. Enrich
467
+ * async (userWithPerms: UserWithPerms) => addPreferences(userWithPerms), // 3. Add prefs
468
+ * async (userWithPosts: UserWithPosts) => addPermissions(userWithPosts), // 2. Add perms
469
+ * async (user: User) => ({ ...user, posts: await fetchUserPosts(user.id) }), // 1. Add posts
470
+ * async (userId: string) => fetchUser(userId) // 0. Fetch user
471
+ * );
472
+ *
473
+ * const enrichedUser = await fetchUserWithPosts('123');
474
+ *
475
+ * @example
476
+ * // Error handling in async composition
477
+ * const safeProcessData = composeAsync(
478
+ * async (result: ProcessResult) => logSuccess(result),
479
+ * async (data: ValidData) => processData(data).catch(err => {
480
+ * console.error('Processing failed:', err);
481
+ * throw err;
482
+ * }),
483
+ * async (raw: unknown) => validateData(raw)
484
+ * );
485
+ *
486
+ * @see pipeAsync - Left-to-right async composition
487
+ * @see compose - Synchronous right-to-left composition
488
+ * @since 2025-07-03
489
+ */
490
+ export declare function composeAsync<A, B>(f1: (a: A) => Promise<B>): (a: A) => Promise<B>;
491
+ export declare function composeAsync<A, B, C>(f2: (b: B) => Promise<C>, f1: (a: A) => Promise<B>): (a: A) => Promise<C>;
492
+ export declare function composeAsync<A, B, C, D>(f3: (c: C) => Promise<D>, f2: (b: B) => Promise<C>, f1: (a: A) => Promise<B>): (a: A) => Promise<D>;
493
+ export declare function composeAsync<A, B, C, D, E>(f4: (d: D) => Promise<E>, f3: (c: C) => Promise<D>, f2: (b: B) => Promise<C>, f1: (a: A) => Promise<B>): (a: A) => Promise<E>;
494
+ export declare function composeAsync<A, B, C, D, E, F>(f5: (e: E) => Promise<F>, f4: (d: D) => Promise<E>, f3: (c: C) => Promise<D>, f2: (b: B) => Promise<C>, f1: (a: A) => Promise<B>): (a: A) => Promise<F>;
495
+ /**
496
+ * Pipe async functions from left to right.
497
+ * Natural reading order for async function composition.
498
+ * Now supports any number of async functions.
499
+ *
500
+ * @category Async
501
+ * @example
502
+ * // Sequential async operations
503
+ * const uploadAndProcess = pipeAsync(
504
+ * async (file: File) => uploadFile(file), // 1. Upload
505
+ * async (url: string) => processImage(url), // 2. Process
506
+ * async (processed: ProcessedImage) => notify(processed) // 3. Notify
507
+ * );
508
+ *
509
+ * const result = await uploadAndProcess(imageFile);
510
+ *
511
+ * @example
512
+ * // API data enrichment with multiple steps
513
+ * const enrichUser = pipeAsync(
514
+ * async (userId: string) => fetchUser(userId),
515
+ * async (user: User) => ({
516
+ * ...user,
517
+ * permissions: await fetchPermissions(user.roleId)
518
+ * }),
519
+ * async (user: UserWithPerms) => ({
520
+ * ...user,
521
+ * preferences: await fetchPreferences(user.id)
522
+ * }),
523
+ * async (user: UserWithPrefs) => ({
524
+ * ...user,
525
+ * analytics: await fetchAnalytics(user.id)
526
+ * }),
527
+ * async (user: FullUser) => cacheUser(user)
528
+ * );
529
+ *
530
+ * const fullUser = await enrichUser('123');
531
+ *
532
+ * @example
533
+ * // Error handling in async pipelines
534
+ * const processOrder = pipeAsync(
535
+ * async (orderId: string) => fetchOrder(orderId),
536
+ * async (order: Order) => validateOrder(order),
537
+ * async (validOrder: ValidOrder) => processPayment(validOrder),
538
+ * async (paidOrder: PaidOrder) => shipOrder(paidOrder),
539
+ * async (shippedOrder: ShippedOrder) => sendConfirmation(shippedOrder)
540
+ * );
541
+ *
542
+ * try {
543
+ * await processOrder('ORDER-123');
544
+ * } catch (error) {
545
+ * console.error('Order processing failed:', error);
546
+ * }
547
+ *
548
+ * @see composeAsync - Right-to-left async composition
549
+ * @see pipe - Synchronous left-to-right composition
550
+ * @since 2025-07-03
551
+ */
552
+ export declare function pipeAsync<A, B>(f1: (a: A) => Promise<B>): (a: A) => Promise<B>;
553
+ export declare function pipeAsync<A, B, C>(f1: (a: A) => Promise<B>, f2: (b: B) => Promise<C>): (a: A) => Promise<C>;
554
+ export declare function pipeAsync<A, B, C, D>(f1: (a: A) => Promise<B>, f2: (b: B) => Promise<C>, f3: (c: C) => Promise<D>): (a: A) => Promise<D>;
555
+ export declare function pipeAsync<A, B, C, D, E>(f1: (a: A) => Promise<B>, f2: (b: B) => Promise<C>, f3: (c: C) => Promise<D>, f4: (d: D) => Promise<E>): (a: A) => Promise<E>;
556
+ export declare function pipeAsync<A, B, C, D, E, F>(f1: (a: A) => Promise<B>, f2: (b: B) => Promise<C>, f3: (c: C) => Promise<D>, f4: (d: D) => Promise<E>, f5: (e: E) => Promise<F>): (a: A) => Promise<F>;
557
+ /**
558
+ * Sequential execution of async functions.
559
+ * @description Executes an array of async functions in order, waiting for each to complete before starting the next.
560
+ * Collects and returns all results in an array. Unlike Promise.all, this ensures sequential execution
561
+ * which is useful when operations depend on each other or when you need to limit concurrency.
562
+ *
563
+ * @template T - The type of values returned by the async functions
564
+ * @param {Array<() => Promise<T>>} fns - Array of async functions to execute
565
+ * @returns {Promise<T[]>} Promise resolving to array of all results in order
566
+ *
567
+ * @category Async
568
+ * @example
569
+ * // Execute initialization steps in order
570
+ * const initSteps = [
571
+ * async () => connectDatabase(),
572
+ * async () => loadConfiguration(),
573
+ * async () => startServer()
574
+ * ];
575
+ *
576
+ * const results = await sequence(initSteps);
577
+ * // All steps completed in order
578
+ *
579
+ * @example
580
+ * // Data fetching sequence
581
+ * const fetchOperations = userIds.map(id =>
582
+ * async () => fetchUserData(id)
583
+ * );
584
+ *
585
+ * const allUserData = await sequence(fetchOperations);
586
+ * // Fetches users one by one, not in parallel
587
+ *
588
+ * @example
589
+ * // Cleanup operations
590
+ * const cleanup = sequence([
591
+ * async () => closeConnections(),
592
+ * async () => flushCache(),
593
+ * async () => logShutdown()
594
+ * ]);
595
+ *
596
+ * process.on('SIGTERM', () => cleanup());
597
+ *
598
+ * @see Promise.all - For parallel execution
599
+ * @see pipeAsync - For composing async functions
600
+ * @since 2025-07-03
601
+ */
602
+ export declare const sequence: <T>(fns: (() => Promise<T>)[]) => Promise<T[]>;
603
+ //# sourceMappingURL=composition.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition.d.mts","sourceRoot":"","sources":["../src/composition.mts"],"names":[],"mappings":"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"}