@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.
- package/README.md +242 -0
- package/dist/array-utils.d.mts +317 -0
- package/dist/array-utils.d.mts.map +1 -0
- package/dist/array-utils.mjs +370 -0
- package/dist/array-utils.mjs.map +1 -0
- package/dist/composition.d.mts +603 -0
- package/dist/composition.d.mts.map +1 -0
- package/dist/composition.mjs +516 -0
- package/dist/composition.mjs.map +1 -0
- package/dist/object-utils.d.mts +267 -0
- package/dist/object-utils.d.mts.map +1 -0
- package/dist/object-utils.mjs +258 -0
- package/dist/object-utils.mjs.map +1 -0
- package/dist/option.d.mts +622 -0
- package/dist/option.d.mts.map +1 -0
- package/dist/option.mjs +637 -0
- package/dist/option.mjs.map +1 -0
- package/dist/performance.d.mts +265 -0
- package/dist/performance.d.mts.map +1 -0
- package/dist/performance.mjs +453 -0
- package/dist/performance.mjs.map +1 -0
- package/dist/pipeline.d.mts +431 -0
- package/dist/pipeline.d.mts.map +1 -0
- package/dist/pipeline.mjs +460 -0
- package/dist/pipeline.mjs.map +1 -0
- package/dist/predicates.d.mts +722 -0
- package/dist/predicates.d.mts.map +1 -0
- package/dist/predicates.mjs +802 -0
- package/dist/predicates.mjs.map +1 -0
- package/dist/reader-result.d.mts +422 -0
- package/dist/reader-result.d.mts.map +1 -0
- package/dist/reader-result.mjs +758 -0
- package/dist/reader-result.mjs.map +1 -0
- package/dist/result.d.mts +684 -0
- package/dist/result.d.mts.map +1 -0
- package/dist/result.mjs +814 -0
- package/dist/result.mjs.map +1 -0
- package/dist/types.d.mts +439 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +191 -0
- package/dist/types.mjs.map +1 -0
- package/dist/validation.d.mts +622 -0
- package/dist/validation.d.mts.map +1 -0
- package/dist/validation.mjs +852 -0
- package/dist/validation.mjs.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module array-utils
|
|
4
|
+
* @description Functional utilities for working with arrays in a type-safe, immutable manner.
|
|
5
|
+
* These functions are designed to be composed and follow functional programming principles.
|
|
6
|
+
* All operations return new arrays, preserving immutability.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { filterMap, chunk, groupBy } from './array-utils.mts';
|
|
11
|
+
*
|
|
12
|
+
* // filter and transform in one pass
|
|
13
|
+
* const numbers = filterMap((s: string) => {
|
|
14
|
+
* const n = parseInt(s);
|
|
15
|
+
* return isNaN(n) ? undefined : n;
|
|
16
|
+
* })(['1', 'a', '2', 'b', '3']);
|
|
17
|
+
* // => [1, 2, 3]
|
|
18
|
+
*
|
|
19
|
+
* // chunk into batches
|
|
20
|
+
* const batches = chunk(3)([1, 2, 3, 4, 5, 6, 7]);
|
|
21
|
+
* // => [[1, 2, 3], [4, 5, 6], [7]]
|
|
22
|
+
*
|
|
23
|
+
* // group by property
|
|
24
|
+
* const users = [
|
|
25
|
+
* { name: 'Alice', role: 'admin' },
|
|
26
|
+
* { name: 'Bob', role: 'user' },
|
|
27
|
+
* { name: 'Charlie', role: 'admin' }
|
|
28
|
+
* ];
|
|
29
|
+
* const byRole = groupBy((u: typeof users[0]) => u.role)(users);
|
|
30
|
+
* // => { admin: [Alice, Charlie], user: [Bob] }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @category Utilities
|
|
34
|
+
* @since 2025-07-03
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* Map over an array with index.
|
|
38
|
+
* @description Transforms each element of an array using a function that receives both the element and its index.
|
|
39
|
+
* Useful when you need both the element and its position during transformation.
|
|
40
|
+
* Preserves the original array and returns a new array with transformed values.
|
|
41
|
+
*
|
|
42
|
+
* @template T - The type of elements in the input array
|
|
43
|
+
* @template U - The type of elements in the output array
|
|
44
|
+
* @param {function(T, number): U} fn - Transformation function that receives item and index
|
|
45
|
+
* @returns {function(T[]): U[]} A function that takes an array and returns the transformed array
|
|
46
|
+
*
|
|
47
|
+
* @category Transformation
|
|
48
|
+
* @example
|
|
49
|
+
* const indexed = mapWithIndex((item, i) => `${i}: ${item}`)(['a', 'b', 'c']);
|
|
50
|
+
* // => ['0: a', '1: b', '2: c']
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* // Creating a numbered list
|
|
54
|
+
* const items = ['First', 'Second', 'Third'];
|
|
55
|
+
* const numbered = mapWithIndex((item, i) => `${i + 1}. ${item}`)(items);
|
|
56
|
+
* // => ['1. First', '2. Second', '3. Third']
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* // Add index metadata to objects
|
|
60
|
+
* const data = [{ name: 'Alice' }, { name: 'Bob' }];
|
|
61
|
+
* const withIndex = mapWithIndex((item, i) => ({ ...item, index: i }))(data);
|
|
62
|
+
* // => [{ name: 'Alice', index: 0 }, { name: 'Bob', index: 1 }]
|
|
63
|
+
*
|
|
64
|
+
* @see map - Standard array map without index
|
|
65
|
+
* @see filterMap - Transform and filter in one pass
|
|
66
|
+
* @since 2025-07-03
|
|
67
|
+
*/
|
|
68
|
+
export var mapWithIndex = function (fn) {
|
|
69
|
+
return function (arr) {
|
|
70
|
+
return arr.map(fn);
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Filter and map in a single pass, removing undefined values.
|
|
75
|
+
* More efficient than chaining filter and map when transformation might return undefined.
|
|
76
|
+
* Optimized to avoid creating intermediate arrays for better memory efficiency.
|
|
77
|
+
*
|
|
78
|
+
* @category Transformation
|
|
79
|
+
* @example
|
|
80
|
+
* const nums = filterMap((s: string) => {
|
|
81
|
+
* const n = parseInt(s);
|
|
82
|
+
* return isNaN(n) ? undefined : n;
|
|
83
|
+
* })(['1', 'a', '2', 'b', '3']);
|
|
84
|
+
* // => [1, 2, 3]
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* // Parse and validate in one pass
|
|
88
|
+
* const parseEmails = filterMap((str: string) => {
|
|
89
|
+
* const trimmed = str.trim();
|
|
90
|
+
* return trimmed.includes('@') ? trimmed : undefined;
|
|
91
|
+
* });
|
|
92
|
+
* parseEmails([' john@example.com', 'invalid', 'jane@test.com ']);
|
|
93
|
+
* // => ['john@example.com', 'jane@test.com']
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* // Extract and transform nested data
|
|
97
|
+
* const users = [
|
|
98
|
+
* { name: 'Alice', profile: { age: 25 } },
|
|
99
|
+
* { name: 'Bob', profile: null },
|
|
100
|
+
* { name: 'Charlie', profile: { age: 30 } }
|
|
101
|
+
* ];
|
|
102
|
+
* const ages = filterMap((u: typeof users[0]) =>
|
|
103
|
+
* u.profile ? { name: u.name, age: u.profile.age } : undefined
|
|
104
|
+
* )(users);
|
|
105
|
+
* // => [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 30 }]
|
|
106
|
+
*
|
|
107
|
+
* @see map - Transform without filtering
|
|
108
|
+
* @see filter - Filter without transformation
|
|
109
|
+
* @since 2025-07-03
|
|
110
|
+
*/
|
|
111
|
+
export var filterMap = function (fn) {
|
|
112
|
+
return function (arr) {
|
|
113
|
+
return arr.reduce(function (acc, item, index) {
|
|
114
|
+
var result = fn(item, index);
|
|
115
|
+
if (result !== undefined) {
|
|
116
|
+
acc.push(result);
|
|
117
|
+
}
|
|
118
|
+
return acc;
|
|
119
|
+
}, []);
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Chunk an array into smaller arrays of specified size.
|
|
124
|
+
* @description Splits an array into multiple sub-arrays of a specified maximum size.
|
|
125
|
+
* The last chunk may contain fewer elements if the array length is not evenly divisible by the chunk size.
|
|
126
|
+
* Useful for pagination, batch processing, or creating grid layouts.
|
|
127
|
+
*
|
|
128
|
+
* @template T - The type of elements in the array
|
|
129
|
+
* @param {number} size - The maximum size of each chunk (must be positive)
|
|
130
|
+
* @returns {function(T[]): T[][]} A function that takes an array and returns an array of chunks
|
|
131
|
+
*
|
|
132
|
+
* @category Grouping
|
|
133
|
+
* @example
|
|
134
|
+
* const chunks = chunk(2)([1, 2, 3, 4, 5]);
|
|
135
|
+
* // => [[1, 2], [3, 4], [5]]
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* // Batch API requests
|
|
139
|
+
* const userIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
140
|
+
* const batches = chunk(3)(userIds);
|
|
141
|
+
* // => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* // Create rows for a grid
|
|
145
|
+
* const items = ['A', 'B', 'C', 'D', 'E', 'F'];
|
|
146
|
+
* const rows = chunk(3)(items);
|
|
147
|
+
* // => [['A', 'B', 'C'], ['D', 'E', 'F']]
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* // Process large dataset in batches
|
|
151
|
+
* const processInBatches = async <T>(items: T[], batchSize: number, processor: (batch: T[]) => Promise<void>) => {
|
|
152
|
+
* const batches = chunk(batchSize)(items);
|
|
153
|
+
* for (const batch of batches) {
|
|
154
|
+
* await processor(batch);
|
|
155
|
+
* }
|
|
156
|
+
* };
|
|
157
|
+
*
|
|
158
|
+
* @see groupBy - Group by a key function
|
|
159
|
+
* @see partition - Split into two arrays
|
|
160
|
+
* @since 2025-07-03
|
|
161
|
+
*/
|
|
162
|
+
export var chunk = function (size) {
|
|
163
|
+
return function (arr) {
|
|
164
|
+
var chunks = [];
|
|
165
|
+
for (var i = 0; i < arr.length; i += size) {
|
|
166
|
+
chunks.push(arr.slice(i, i + size));
|
|
167
|
+
}
|
|
168
|
+
return chunks;
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* Group array elements by a key function.
|
|
173
|
+
* @description Creates an object where keys are the grouping values and values are arrays of elements.
|
|
174
|
+
* Each element is placed into exactly one group based on the key function result.
|
|
175
|
+
* The order of elements within each group is preserved from the original array.
|
|
176
|
+
*
|
|
177
|
+
* @template T - The type of elements in the array
|
|
178
|
+
* @template K - The type of the grouping key (must be string or number)
|
|
179
|
+
* @param {function(T): K} keyFn - Function that extracts the grouping key from each element
|
|
180
|
+
* @returns {function(T[]): Record<K, T[]>} A function that takes an array and returns grouped elements
|
|
181
|
+
*
|
|
182
|
+
* @category Grouping
|
|
183
|
+
* @example
|
|
184
|
+
* const users = [
|
|
185
|
+
* { name: 'Alice', age: 25 },
|
|
186
|
+
* { name: 'Bob', age: 30 },
|
|
187
|
+
* { name: 'Charlie', age: 25 }
|
|
188
|
+
* ];
|
|
189
|
+
* const byAge = groupBy((u: typeof users[0]) => u.age)(users);
|
|
190
|
+
* // => { 25: [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }], 30: [{ name: 'Bob', age: 30 }] }
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* // Group by first letter
|
|
194
|
+
* const words = ['apple', 'banana', 'apricot', 'cherry', 'avocado'];
|
|
195
|
+
* const byFirstLetter = groupBy((word: string) => word[0])(words);
|
|
196
|
+
* // => { a: ['apple', 'apricot', 'avocado'], b: ['banana'], c: ['cherry'] }
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* // Group transactions by status
|
|
200
|
+
* const transactions = [
|
|
201
|
+
* { id: 1, status: 'pending', amount: 100 },
|
|
202
|
+
* { id: 2, status: 'completed', amount: 200 },
|
|
203
|
+
* { id: 3, status: 'pending', amount: 150 }
|
|
204
|
+
* ];
|
|
205
|
+
* const byStatus = groupBy((t: typeof transactions[0]) => t.status)(transactions);
|
|
206
|
+
* // => { pending: [{id: 1, ...}, {id: 3, ...}], completed: [{id: 2, ...}] }
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* // Group by computed property
|
|
210
|
+
* const scores = [65, 72, 88, 95, 42, 58, 90];
|
|
211
|
+
* const byGrade = groupBy((score: number) => {
|
|
212
|
+
* if (score >= 90) return 'A';
|
|
213
|
+
* if (score >= 80) return 'B';
|
|
214
|
+
* if (score >= 70) return 'C';
|
|
215
|
+
* if (score >= 60) return 'D';
|
|
216
|
+
* return 'F';
|
|
217
|
+
* })(scores);
|
|
218
|
+
* // => { A: [95, 90], B: [88], C: [72], D: [65], F: [42, 58] }
|
|
219
|
+
*
|
|
220
|
+
* @see chunk - Group into fixed-size arrays
|
|
221
|
+
* @see partition - Split into two groups
|
|
222
|
+
* @since 2025-07-03
|
|
223
|
+
*/
|
|
224
|
+
export var groupBy = function (keyFn) {
|
|
225
|
+
return function (arr) {
|
|
226
|
+
var groups = {};
|
|
227
|
+
for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) {
|
|
228
|
+
var item = arr_1[_i];
|
|
229
|
+
var key = keyFn(item);
|
|
230
|
+
if (!groups[key]) {
|
|
231
|
+
groups[key] = [];
|
|
232
|
+
}
|
|
233
|
+
groups[key].push(item);
|
|
234
|
+
}
|
|
235
|
+
return groups;
|
|
236
|
+
};
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* Find the first item that matches a predicate, returning a Result.
|
|
240
|
+
* @description Safe alternative to Array.find that explicitly handles the not-found case.
|
|
241
|
+
* Returns a discriminated union result that forces explicit handling of both success and failure cases.
|
|
242
|
+
* This prevents runtime errors from undefined values and makes the control flow explicit.
|
|
243
|
+
*
|
|
244
|
+
* @template T - The type of elements in the array
|
|
245
|
+
* @param {function(T): boolean} predicate - Function to test each element
|
|
246
|
+
* @returns {function(T[]): { success: true; data: T } | { success: false; error: string }} A function that searches the array and returns a Result
|
|
247
|
+
*
|
|
248
|
+
* @category Search
|
|
249
|
+
* @example
|
|
250
|
+
* const result = findSafe((n: number) => n > 3)([1, 2, 3, 4, 5]);
|
|
251
|
+
* // => { success: true, data: 4 }
|
|
252
|
+
*
|
|
253
|
+
* const notFound = findSafe((n: number) => n > 10)([1, 2, 3]);
|
|
254
|
+
* // => { success: false, error: 'Item not found' }
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* // Find user by email
|
|
258
|
+
* const users = [
|
|
259
|
+
* { id: 1, email: 'alice@example.com' },
|
|
260
|
+
* { id: 2, email: 'bob@example.com' }
|
|
261
|
+
* ];
|
|
262
|
+
* const findByEmail = (email: string) =>
|
|
263
|
+
* findSafe((u: typeof users[0]) => u.email === email)(users);
|
|
264
|
+
*
|
|
265
|
+
* const result = findByEmail('alice@example.com');
|
|
266
|
+
* if (result.success) {
|
|
267
|
+
* console.log('Found user:', result.data.id);
|
|
268
|
+
* } else {
|
|
269
|
+
* console.log('User not found');
|
|
270
|
+
* }
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* // Chain with other operations safely
|
|
274
|
+
* const processUser = (email: string) => {
|
|
275
|
+
* const result = findSafe((u: User) => u.email === email)(users);
|
|
276
|
+
* if (!result.success) {
|
|
277
|
+
* return { success: false, error: `No user with email ${email}` };
|
|
278
|
+
* }
|
|
279
|
+
* // process result.data safely
|
|
280
|
+
* return { success: true, data: processUserData(result.data) };
|
|
281
|
+
* };
|
|
282
|
+
*
|
|
283
|
+
* @see find - Native array find (returns undefined)
|
|
284
|
+
* @see filter - Get all matching items
|
|
285
|
+
* @since 2025-07-03
|
|
286
|
+
*/
|
|
287
|
+
export var findSafe = function (predicate) {
|
|
288
|
+
return function (arr) {
|
|
289
|
+
var found = arr.find(predicate);
|
|
290
|
+
if (found !== undefined) {
|
|
291
|
+
return { success: true, data: found };
|
|
292
|
+
}
|
|
293
|
+
return { success: false, error: "Item not found" };
|
|
294
|
+
};
|
|
295
|
+
};
|
|
296
|
+
/**
|
|
297
|
+
* Partition an array into two arrays based on a predicate.
|
|
298
|
+
* @description Splits an array into two parts: elements that satisfy the predicate go into the first array,
|
|
299
|
+
* and elements that don't satisfy the predicate go into the second array.
|
|
300
|
+
* More efficient than running filter twice with opposite predicates.
|
|
301
|
+
* Preserves the relative order of elements in both resulting arrays.
|
|
302
|
+
*
|
|
303
|
+
* @template T - The type of elements in the array
|
|
304
|
+
* @param {function(T): boolean} predicate - Function to test each element
|
|
305
|
+
* @returns {function(T[]): [T[], T[]]} A function that takes an array and returns a tuple of [matching, non-matching] arrays
|
|
306
|
+
*
|
|
307
|
+
* @category Grouping
|
|
308
|
+
* @example
|
|
309
|
+
* const [evens, odds] = partition((n: number) => n % 2 === 0)([1, 2, 3, 4, 5]);
|
|
310
|
+
* // => evens: [2, 4], odds: [1, 3, 5]
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* // Separate valid and invalid data
|
|
314
|
+
* const data = [
|
|
315
|
+
* { id: 1, valid: true },
|
|
316
|
+
* { id: 2, valid: false },
|
|
317
|
+
* { id: 3, valid: true }
|
|
318
|
+
* ];
|
|
319
|
+
* const [valid, invalid] = partition((item: typeof data[0]) => item.valid)(data);
|
|
320
|
+
* // => valid: [{id: 1, valid: true}, {id: 3, valid: true}]
|
|
321
|
+
* // => invalid: [{id: 2, valid: false}]
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* // Separate active and inactive users
|
|
325
|
+
* const users = [
|
|
326
|
+
* { name: 'Alice', lastLogin: new Date('2024-01-10') },
|
|
327
|
+
* { name: 'Bob', lastLogin: new Date('2023-12-01') },
|
|
328
|
+
* { name: 'Charlie', lastLogin: new Date('2024-01-14') }
|
|
329
|
+
* ];
|
|
330
|
+
* const thirtyDaysAgo = new Date();
|
|
331
|
+
* thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
|
|
332
|
+
*
|
|
333
|
+
* const [active, inactive] = partition(
|
|
334
|
+
* (u: typeof users[0]) => u.lastLogin > thirtyDaysAgo
|
|
335
|
+
* )(users);
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* // Partition by multiple criteria
|
|
339
|
+
* const products = [
|
|
340
|
+
* { name: 'Laptop', price: 1200, inStock: true },
|
|
341
|
+
* { name: 'Mouse', price: 25, inStock: false },
|
|
342
|
+
* { name: 'Keyboard', price: 80, inStock: true }
|
|
343
|
+
* ];
|
|
344
|
+
* const [available, unavailable] = partition(
|
|
345
|
+
* (p: typeof products[0]) => p.inStock && p.price < 1000
|
|
346
|
+
* )(products);
|
|
347
|
+
* // => available: [{ name: 'Keyboard', ... }]
|
|
348
|
+
* // => unavailable: [{ name: 'Laptop', ... }, { name: 'Mouse', ... }]
|
|
349
|
+
*
|
|
350
|
+
* @see filter - Get only matching items
|
|
351
|
+
* @see groupBy - Group into multiple categories
|
|
352
|
+
* @since 2025-07-03
|
|
353
|
+
*/
|
|
354
|
+
export var partition = function (predicate) {
|
|
355
|
+
return function (arr) {
|
|
356
|
+
var left = [];
|
|
357
|
+
var right = [];
|
|
358
|
+
for (var _i = 0, arr_2 = arr; _i < arr_2.length; _i++) {
|
|
359
|
+
var item = arr_2[_i];
|
|
360
|
+
if (predicate(item)) {
|
|
361
|
+
left.push(item);
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
right.push(item);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return [left, right];
|
|
368
|
+
};
|
|
369
|
+
};
|
|
370
|
+
//# sourceMappingURL=array-utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array-utils.mjs","sourceRoot":"","sources":["../src/array-utils.mts"],"names":[],"mappings":"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"}
|