@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
package/README.md ADDED
@@ -0,0 +1,242 @@
1
+ # Functional Library
2
+
3
+ A comprehensive collection of functional programming utilities for TypeScript, designed to promote immutability, composability, and type safety.
4
+
5
+ ## Overview
6
+
7
+ This library provides a set of pure, composable functions that follow functional programming principles. All utilities are designed to be tree-shakeable, type-safe, and optimized for performance.
8
+
9
+ ## Architecture Principles
10
+
11
+ - **Pure Functions**: All utilities are pure functions with no side effects
12
+ - **Immutability**: Functions never mutate input data, always returning new values
13
+ - **Composability**: Designed to work together through function composition
14
+ - **Type Safety**: Full TypeScript support with comprehensive type inference
15
+ - **Tree-Shaking**: No barrel exports - import directly from specific modules
16
+ - **Performance**: Optimized implementations with minimal overhead
17
+
18
+ ## Modules
19
+
20
+ ### `array-utils.mts`
21
+
22
+ Functional utilities for array manipulation and transformation.
23
+
24
+ **Functions:**
25
+
26
+ - `mapWithIndex` - Map with access to element index
27
+ - `filterMap` - Combined filter and map in a single pass
28
+ - `chunk` - Split array into chunks of specified size
29
+ - `groupBy` - Group elements by a key function
30
+ - `findSafe` - Type-safe array element finder returning Result type
31
+ - `partition` - Split array into two based on predicate
32
+
33
+ ### `object-utils.mts`
34
+
35
+ Utilities for immutable object operations.
36
+
37
+ **Functions:**
38
+
39
+ - `mapValues` - Transform object values while preserving keys
40
+ - `pick` - Create new object with selected keys
41
+ - `omit` - Create new object without specified keys
42
+ - `merge` - Deep merge objects with type safety
43
+
44
+ ### `composition.mts`
45
+
46
+ Core function composition utilities.
47
+
48
+ **Functions:**
49
+
50
+ - `pipe` - Left-to-right function composition
51
+ - `pipeAsync` - Async function pipeline
52
+ - `compose` - Right-to-left function composition
53
+ - `composeAsync` - Async function composition
54
+ - `flow` - Type-safe variadic pipe
55
+ - `flowAsync` - Type-safe variadic async pipe
56
+ - `tap` - Side effect injection
57
+ - `curry` - Function currying
58
+ - `partial` - Partial application
59
+ - `flip` - Flip function arguments
60
+ - `memoize` - Function memoization
61
+ - `constant` - Create constant function
62
+ - `identity` - Identity function
63
+ - `noop` - No-operation function
64
+
65
+ ### `predicates.mts`
66
+
67
+ Predicate functions and logical combinators.
68
+
69
+ **Functions:**
70
+
71
+ - `and` - Logical AND combinator
72
+ - `or` - Logical OR combinator
73
+ - `not` - Logical NOT combinator
74
+ - `xor` - Logical XOR combinator
75
+ - `isNil` - Check for null or undefined
76
+ - `isNotNil` - Check for non-null/undefined
77
+ - `isEmpty` - Check for empty values
78
+ - `isNotEmpty` - Check for non-empty values
79
+ - `equals` - Deep equality check
80
+ - `oneOf` - Check if value is in array
81
+ - `inRange` - Check if number is in range
82
+ - `matches` - Partial object matching
83
+ - `hasProperty` - Property existence check
84
+ - `includes` - Substring/array element check
85
+ - `alwaysTrue` - Constant true predicate
86
+ - `alwaysFalse` - Constant false predicate
87
+
88
+ ### `performance.mts`
89
+
90
+ Performance optimization utilities.
91
+
92
+ **Functions:**
93
+
94
+ - `debounce` - Delay function execution
95
+ - `throttle` - Rate limit function calls
96
+ - `batchAsync` - Batch async operations
97
+ - `performanceUtils.measure` - Measure function execution time
98
+
99
+ ### `pipeline.mts`
100
+
101
+ Fluent pipeline API for chaining operations.
102
+
103
+ **Class:**
104
+
105
+ - `Pipeline` - Chainable transformation pipeline with methods:
106
+ - `map` - Transform value
107
+ - `flatMap` - Transform and flatten
108
+ - `filter` - Conditional transformation
109
+ - `tap` - Side effects
110
+ - `pipeAsync` - Async transformations
111
+ - `value` - Extract final value
112
+
113
+ ### `result.mts`
114
+
115
+ Result type for explicit error handling without exceptions.
116
+
117
+ **Types & Functions:**
118
+
119
+ - `Result<T, E>` - Success or error union type
120
+ - `Result.ok` - Create success result
121
+ - `Result.err` - Create error result
122
+ - `Result.map` - Transform success value
123
+ - `Result.mapError` - Transform error value
124
+ - `Result.chain` - Monadic bind
125
+ - `Result.match` - Pattern matching
126
+ - `Result.isOk` - Type guard for success
127
+ - `Result.isErr` - Type guard for error
128
+
129
+ ### `reader-result.mts`
130
+
131
+ Reader monad combined with Result type for dependency injection and error handling.
132
+
133
+ **Types & Functions:**
134
+
135
+ - `ReaderResult<D, E, A>` - Reader + Result monad
136
+ - `ReaderResult.of` - Create from value
137
+ - `ReaderResult.fromResult` - Lift Result
138
+ - `ReaderResult.ask` - Access dependencies
139
+ - `ReaderResult.chain` - Monadic composition
140
+ - `ReaderResult.map` - Transform success value
141
+ - `ReaderResult.run` - Execute with dependencies
142
+
143
+ ### `validation.mts`
144
+
145
+ Validation utilities and error types.
146
+
147
+ **Types & Functions:**
148
+
149
+ - `ValidationError` - Structured validation error
150
+ - `createValidationError` - Error factory
151
+ - `combineValidationErrors` - Merge multiple errors
152
+ - `formatValidationError` - Error formatting
153
+
154
+ ## Usage Patterns
155
+
156
+ ### Import Strategy
157
+
158
+ Always import directly from specific modules for optimal tree-shaking:
159
+
160
+ ```typescript
161
+ // ✅ Correct - Direct imports
162
+ import { pipe, compose } from "@/lib/functional/composition.mjs";
163
+ import { mapValues, pick } from "@/lib/functional/object-utils.mjs";
164
+
165
+ // ❌ Wrong - No barrel imports (index.mts was removed)
166
+ import { pipe } from "@/lib/functional";
167
+ ```
168
+
169
+ ### Composition Patterns
170
+
171
+ Functions are designed to work together through composition:
172
+
173
+ ```typescript
174
+ import { chunk, filterMap } from "@/lib/functional/array-utils.mjs";
175
+ import { pipe } from "@/lib/functional/composition.mjs";
176
+ import { isNotNil } from "@/lib/functional/predicates.mjs";
177
+
178
+ // Combine utilities for complex transformations
179
+ const processData = pipe(
180
+ filterMap((x: unknown) => (isNotNil(x) ? x : undefined)),
181
+ chunk(10),
182
+ );
183
+ ```
184
+
185
+ ### Error Handling
186
+
187
+ Use Result types for explicit error handling:
188
+
189
+ ```typescript
190
+ import { findSafe } from "@/lib/functional/array-utils.mjs";
191
+ import { Result } from "@/lib/functional/result.mjs";
192
+
193
+ // Functions return Result types for safety
194
+ const result = findSafe((x: User) => x.id === targetId)(users);
195
+
196
+ if (result.success) {
197
+ console.log("Found user:", result.data);
198
+ } else {
199
+ console.log("User not found");
200
+ }
201
+ ```
202
+
203
+ ## Testing
204
+
205
+ All utilities have comprehensive test suites. Run tests with:
206
+
207
+ ```bash
208
+ # Run all functional library tests
209
+ pnpm test src/lib/functional
210
+
211
+ # Run specific module tests
212
+ pnpm test src/lib/functional/array-utils.test.ts
213
+ ```
214
+
215
+ ## Performance Considerations
216
+
217
+ - **Memory Efficiency**: Functions like `filterMap` avoid intermediate arrays
218
+ - **Lazy Evaluation**: Pipeline class enables lazy transformation chains
219
+ - **Memoization**: Use `memoize` for expensive pure computations
220
+ - **Batching**: `batchAsync` optimizes concurrent async operations
221
+
222
+ ## Migration Guide
223
+
224
+ If migrating from the old structure:
225
+
226
+ 1. Replace imports from `pipe.mts` with `composition.mts`
227
+ 2. Import array/object utilities from their dedicated modules
228
+ 3. Remove any imports from `index.mts` (barrel file removed)
229
+ 4. Update type imports for Result and ValidationError
230
+
231
+ ## Contributing
232
+
233
+ When adding new utilities:
234
+
235
+ 1. Ensure functions are pure with no side effects
236
+ 2. Add comprehensive JSDoc with `@example` blocks
237
+ 3. Include proper `@since` tags with current date
238
+ 4. Write thorough unit tests
239
+ 5. Follow established naming conventions
240
+ 6. Update this README with new functions
241
+
242
+ ## License - MIT
@@ -0,0 +1,317 @@
1
+ /**
2
+ * @module array-utils
3
+ * @description Functional utilities for working with arrays in a type-safe, immutable manner.
4
+ * These functions are designed to be composed and follow functional programming principles.
5
+ * All operations return new arrays, preserving immutability.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { filterMap, chunk, groupBy } from './array-utils.mts';
10
+ *
11
+ * // filter and transform in one pass
12
+ * const numbers = filterMap((s: string) => {
13
+ * const n = parseInt(s);
14
+ * return isNaN(n) ? undefined : n;
15
+ * })(['1', 'a', '2', 'b', '3']);
16
+ * // => [1, 2, 3]
17
+ *
18
+ * // chunk into batches
19
+ * const batches = chunk(3)([1, 2, 3, 4, 5, 6, 7]);
20
+ * // => [[1, 2, 3], [4, 5, 6], [7]]
21
+ *
22
+ * // group by property
23
+ * const users = [
24
+ * { name: 'Alice', role: 'admin' },
25
+ * { name: 'Bob', role: 'user' },
26
+ * { name: 'Charlie', role: 'admin' }
27
+ * ];
28
+ * const byRole = groupBy((u: typeof users[0]) => u.role)(users);
29
+ * // => { admin: [Alice, Charlie], user: [Bob] }
30
+ * ```
31
+ *
32
+ * @category Utilities
33
+ * @since 2025-07-03
34
+ */
35
+ /**
36
+ * Map over an array with index.
37
+ * @description Transforms each element of an array using a function that receives both the element and its index.
38
+ * Useful when you need both the element and its position during transformation.
39
+ * Preserves the original array and returns a new array with transformed values.
40
+ *
41
+ * @template T - The type of elements in the input array
42
+ * @template U - The type of elements in the output array
43
+ * @param {function(T, number): U} fn - Transformation function that receives item and index
44
+ * @returns {function(T[]): U[]} A function that takes an array and returns the transformed array
45
+ *
46
+ * @category Transformation
47
+ * @example
48
+ * const indexed = mapWithIndex((item, i) => `${i}: ${item}`)(['a', 'b', 'c']);
49
+ * // => ['0: a', '1: b', '2: c']
50
+ *
51
+ * @example
52
+ * // Creating a numbered list
53
+ * const items = ['First', 'Second', 'Third'];
54
+ * const numbered = mapWithIndex((item, i) => `${i + 1}. ${item}`)(items);
55
+ * // => ['1. First', '2. Second', '3. Third']
56
+ *
57
+ * @example
58
+ * // Add index metadata to objects
59
+ * const data = [{ name: 'Alice' }, { name: 'Bob' }];
60
+ * const withIndex = mapWithIndex((item, i) => ({ ...item, index: i }))(data);
61
+ * // => [{ name: 'Alice', index: 0 }, { name: 'Bob', index: 1 }]
62
+ *
63
+ * @see map - Standard array map without index
64
+ * @see filterMap - Transform and filter in one pass
65
+ * @since 2025-07-03
66
+ */
67
+ export declare const mapWithIndex: <T, U>(fn: (item: T, index: number) => U) => (arr: T[]) => U[];
68
+ /**
69
+ * Filter and map in a single pass, removing undefined values.
70
+ * More efficient than chaining filter and map when transformation might return undefined.
71
+ * Optimized to avoid creating intermediate arrays for better memory efficiency.
72
+ *
73
+ * @category Transformation
74
+ * @example
75
+ * const nums = filterMap((s: string) => {
76
+ * const n = parseInt(s);
77
+ * return isNaN(n) ? undefined : n;
78
+ * })(['1', 'a', '2', 'b', '3']);
79
+ * // => [1, 2, 3]
80
+ *
81
+ * @example
82
+ * // Parse and validate in one pass
83
+ * const parseEmails = filterMap((str: string) => {
84
+ * const trimmed = str.trim();
85
+ * return trimmed.includes('@') ? trimmed : undefined;
86
+ * });
87
+ * parseEmails([' john@example.com', 'invalid', 'jane@test.com ']);
88
+ * // => ['john@example.com', 'jane@test.com']
89
+ *
90
+ * @example
91
+ * // Extract and transform nested data
92
+ * const users = [
93
+ * { name: 'Alice', profile: { age: 25 } },
94
+ * { name: 'Bob', profile: null },
95
+ * { name: 'Charlie', profile: { age: 30 } }
96
+ * ];
97
+ * const ages = filterMap((u: typeof users[0]) =>
98
+ * u.profile ? { name: u.name, age: u.profile.age } : undefined
99
+ * )(users);
100
+ * // => [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 30 }]
101
+ *
102
+ * @see map - Transform without filtering
103
+ * @see filter - Filter without transformation
104
+ * @since 2025-07-03
105
+ */
106
+ export declare const filterMap: <T, U>(fn: (item: T, index: number) => U | undefined) => (arr: T[]) => U[];
107
+ /**
108
+ * Chunk an array into smaller arrays of specified size.
109
+ * @description Splits an array into multiple sub-arrays of a specified maximum size.
110
+ * The last chunk may contain fewer elements if the array length is not evenly divisible by the chunk size.
111
+ * Useful for pagination, batch processing, or creating grid layouts.
112
+ *
113
+ * @template T - The type of elements in the array
114
+ * @param {number} size - The maximum size of each chunk (must be positive)
115
+ * @returns {function(T[]): T[][]} A function that takes an array and returns an array of chunks
116
+ *
117
+ * @category Grouping
118
+ * @example
119
+ * const chunks = chunk(2)([1, 2, 3, 4, 5]);
120
+ * // => [[1, 2], [3, 4], [5]]
121
+ *
122
+ * @example
123
+ * // Batch API requests
124
+ * const userIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
125
+ * const batches = chunk(3)(userIds);
126
+ * // => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
127
+ *
128
+ * @example
129
+ * // Create rows for a grid
130
+ * const items = ['A', 'B', 'C', 'D', 'E', 'F'];
131
+ * const rows = chunk(3)(items);
132
+ * // => [['A', 'B', 'C'], ['D', 'E', 'F']]
133
+ *
134
+ * @example
135
+ * // Process large dataset in batches
136
+ * const processInBatches = async <T>(items: T[], batchSize: number, processor: (batch: T[]) => Promise<void>) => {
137
+ * const batches = chunk(batchSize)(items);
138
+ * for (const batch of batches) {
139
+ * await processor(batch);
140
+ * }
141
+ * };
142
+ *
143
+ * @see groupBy - Group by a key function
144
+ * @see partition - Split into two arrays
145
+ * @since 2025-07-03
146
+ */
147
+ export declare const chunk: <T>(size: number) => (arr: T[]) => T[][];
148
+ /**
149
+ * Group array elements by a key function.
150
+ * @description Creates an object where keys are the grouping values and values are arrays of elements.
151
+ * Each element is placed into exactly one group based on the key function result.
152
+ * The order of elements within each group is preserved from the original array.
153
+ *
154
+ * @template T - The type of elements in the array
155
+ * @template K - The type of the grouping key (must be string or number)
156
+ * @param {function(T): K} keyFn - Function that extracts the grouping key from each element
157
+ * @returns {function(T[]): Record<K, T[]>} A function that takes an array and returns grouped elements
158
+ *
159
+ * @category Grouping
160
+ * @example
161
+ * const users = [
162
+ * { name: 'Alice', age: 25 },
163
+ * { name: 'Bob', age: 30 },
164
+ * { name: 'Charlie', age: 25 }
165
+ * ];
166
+ * const byAge = groupBy((u: typeof users[0]) => u.age)(users);
167
+ * // => { 25: [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }], 30: [{ name: 'Bob', age: 30 }] }
168
+ *
169
+ * @example
170
+ * // Group by first letter
171
+ * const words = ['apple', 'banana', 'apricot', 'cherry', 'avocado'];
172
+ * const byFirstLetter = groupBy((word: string) => word[0])(words);
173
+ * // => { a: ['apple', 'apricot', 'avocado'], b: ['banana'], c: ['cherry'] }
174
+ *
175
+ * @example
176
+ * // Group transactions by status
177
+ * const transactions = [
178
+ * { id: 1, status: 'pending', amount: 100 },
179
+ * { id: 2, status: 'completed', amount: 200 },
180
+ * { id: 3, status: 'pending', amount: 150 }
181
+ * ];
182
+ * const byStatus = groupBy((t: typeof transactions[0]) => t.status)(transactions);
183
+ * // => { pending: [{id: 1, ...}, {id: 3, ...}], completed: [{id: 2, ...}] }
184
+ *
185
+ * @example
186
+ * // Group by computed property
187
+ * const scores = [65, 72, 88, 95, 42, 58, 90];
188
+ * const byGrade = groupBy((score: number) => {
189
+ * if (score >= 90) return 'A';
190
+ * if (score >= 80) return 'B';
191
+ * if (score >= 70) return 'C';
192
+ * if (score >= 60) return 'D';
193
+ * return 'F';
194
+ * })(scores);
195
+ * // => { A: [95, 90], B: [88], C: [72], D: [65], F: [42, 58] }
196
+ *
197
+ * @see chunk - Group into fixed-size arrays
198
+ * @see partition - Split into two groups
199
+ * @since 2025-07-03
200
+ */
201
+ export declare const groupBy: <T, K extends string | number>(keyFn: (item: T) => K) => (arr: T[]) => Record<K, T[]>;
202
+ /**
203
+ * Find the first item that matches a predicate, returning a Result.
204
+ * @description Safe alternative to Array.find that explicitly handles the not-found case.
205
+ * Returns a discriminated union result that forces explicit handling of both success and failure cases.
206
+ * This prevents runtime errors from undefined values and makes the control flow explicit.
207
+ *
208
+ * @template T - The type of elements in the array
209
+ * @param {function(T): boolean} predicate - Function to test each element
210
+ * @returns {function(T[]): { success: true; data: T } | { success: false; error: string }} A function that searches the array and returns a Result
211
+ *
212
+ * @category Search
213
+ * @example
214
+ * const result = findSafe((n: number) => n > 3)([1, 2, 3, 4, 5]);
215
+ * // => { success: true, data: 4 }
216
+ *
217
+ * const notFound = findSafe((n: number) => n > 10)([1, 2, 3]);
218
+ * // => { success: false, error: 'Item not found' }
219
+ *
220
+ * @example
221
+ * // Find user by email
222
+ * const users = [
223
+ * { id: 1, email: 'alice@example.com' },
224
+ * { id: 2, email: 'bob@example.com' }
225
+ * ];
226
+ * const findByEmail = (email: string) =>
227
+ * findSafe((u: typeof users[0]) => u.email === email)(users);
228
+ *
229
+ * const result = findByEmail('alice@example.com');
230
+ * if (result.success) {
231
+ * console.log('Found user:', result.data.id);
232
+ * } else {
233
+ * console.log('User not found');
234
+ * }
235
+ *
236
+ * @example
237
+ * // Chain with other operations safely
238
+ * const processUser = (email: string) => {
239
+ * const result = findSafe((u: User) => u.email === email)(users);
240
+ * if (!result.success) {
241
+ * return { success: false, error: `No user with email ${email}` };
242
+ * }
243
+ * // process result.data safely
244
+ * return { success: true, data: processUserData(result.data) };
245
+ * };
246
+ *
247
+ * @see find - Native array find (returns undefined)
248
+ * @see filter - Get all matching items
249
+ * @since 2025-07-03
250
+ */
251
+ export declare const findSafe: <T>(predicate: (item: T) => boolean) => (arr: T[]) => {
252
+ success: true;
253
+ data: T;
254
+ } | {
255
+ success: false;
256
+ error: string;
257
+ };
258
+ /**
259
+ * Partition an array into two arrays based on a predicate.
260
+ * @description Splits an array into two parts: elements that satisfy the predicate go into the first array,
261
+ * and elements that don't satisfy the predicate go into the second array.
262
+ * More efficient than running filter twice with opposite predicates.
263
+ * Preserves the relative order of elements in both resulting arrays.
264
+ *
265
+ * @template T - The type of elements in the array
266
+ * @param {function(T): boolean} predicate - Function to test each element
267
+ * @returns {function(T[]): [T[], T[]]} A function that takes an array and returns a tuple of [matching, non-matching] arrays
268
+ *
269
+ * @category Grouping
270
+ * @example
271
+ * const [evens, odds] = partition((n: number) => n % 2 === 0)([1, 2, 3, 4, 5]);
272
+ * // => evens: [2, 4], odds: [1, 3, 5]
273
+ *
274
+ * @example
275
+ * // Separate valid and invalid data
276
+ * const data = [
277
+ * { id: 1, valid: true },
278
+ * { id: 2, valid: false },
279
+ * { id: 3, valid: true }
280
+ * ];
281
+ * const [valid, invalid] = partition((item: typeof data[0]) => item.valid)(data);
282
+ * // => valid: [{id: 1, valid: true}, {id: 3, valid: true}]
283
+ * // => invalid: [{id: 2, valid: false}]
284
+ *
285
+ * @example
286
+ * // Separate active and inactive users
287
+ * const users = [
288
+ * { name: 'Alice', lastLogin: new Date('2024-01-10') },
289
+ * { name: 'Bob', lastLogin: new Date('2023-12-01') },
290
+ * { name: 'Charlie', lastLogin: new Date('2024-01-14') }
291
+ * ];
292
+ * const thirtyDaysAgo = new Date();
293
+ * thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
294
+ *
295
+ * const [active, inactive] = partition(
296
+ * (u: typeof users[0]) => u.lastLogin > thirtyDaysAgo
297
+ * )(users);
298
+ *
299
+ * @example
300
+ * // Partition by multiple criteria
301
+ * const products = [
302
+ * { name: 'Laptop', price: 1200, inStock: true },
303
+ * { name: 'Mouse', price: 25, inStock: false },
304
+ * { name: 'Keyboard', price: 80, inStock: true }
305
+ * ];
306
+ * const [available, unavailable] = partition(
307
+ * (p: typeof products[0]) => p.inStock && p.price < 1000
308
+ * )(products);
309
+ * // => available: [{ name: 'Keyboard', ... }]
310
+ * // => unavailable: [{ name: 'Laptop', ... }, { name: 'Mouse', ... }]
311
+ *
312
+ * @see filter - Get only matching items
313
+ * @see groupBy - Group into multiple categories
314
+ * @since 2025-07-03
315
+ */
316
+ export declare const partition: <T>(predicate: (item: T) => boolean) => (arr: T[]) => [T[], T[]];
317
+ //# sourceMappingURL=array-utils.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array-utils.d.mts","sourceRoot":"","sources":["../src/array-utils.mts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,YAAY,GACtB,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,WAClC,CAAC,EAAE,KAAG,CAAC,EACA,CAAC;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,eAAO,MAAM,SAAS,GACnB,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS,WAC9C,CAAC,EAAE,KAAG,CAAC,EAOL,CAAC;AAEX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,KAAK,GACf,CAAC,QAAS,MAAM,WACX,CAAC,EAAE,KAAG,CAAC,EAAE,EAMd,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,eAAO,MAAM,OAAO,GACjB,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,WAC9C,CAAC,EAAE,KAAG,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAUxB,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,eAAO,MAAM,QAAQ,GAClB,CAAC,aAAc,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,WAE7B,CAAC,EAAE,KACP;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAM9D,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,eAAO,MAAM,SAAS,GACnB,CAAC,aAAc,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,WAC9B,CAAC,EAAE,KAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAWpB,CAAC"}