@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,265 @@
1
+ /**
2
+ * @module performance
3
+ * @description Functional utilities for optimizing performance through timing control,
4
+ * batching, and caching. These utilities help manage expensive operations
5
+ * and prevent performance issues in applications. All utilities are designed
6
+ * to be composable and work well with functional programming patterns.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { debounce, throttle, batch, cache, Performance } from './performance.mts';
11
+ *
12
+ * // debounce user input
13
+ * const search = debounce((query: string) => {
14
+ * performSearch(query);
15
+ * }, 300);
16
+ *
17
+ * // throttle scroll events
18
+ * const handleScroll = throttle(() => {
19
+ * updateScrollPosition();
20
+ * }, 100);
21
+ *
22
+ * // batch API calls
23
+ * const saveItem = batch<Item>(async (items) => {
24
+ * await api.saveMany(items);
25
+ * }, { maxSize: 100, maxWait: 1000 });
26
+ *
27
+ * // cache expensive computations
28
+ * const fibonacci = cache((n: number): number => {
29
+ * if (n <= 1) return n;
30
+ * return fibonacci(n - 1) + fibonacci(n - 2);
31
+ * });
32
+ * ```
33
+ *
34
+ * @category Performance
35
+ * @since 2025-07-03
36
+ */
37
+ /**
38
+ * Debounce function execution.
39
+ * @description Delays invoking the function until after the specified delay has elapsed
40
+ * since the last time it was invoked. Useful for expensive operations triggered
41
+ * by user input like search or resize events. Each new call resets the timer.
42
+ *
43
+ * @template T - The types of the function arguments
44
+ * @param {function(...T): void} fn - The function to debounce
45
+ * @param {number} delay - The delay in milliseconds
46
+ * @returns {function(...T): void} The debounced function
47
+ *
48
+ * @category Timing
49
+ * @example
50
+ * // Basic debounce
51
+ * const saveChanges = debounce((text: string) => {
52
+ * console.log('Saving:', text);
53
+ * }, 1000);
54
+ *
55
+ * saveChanges('H');
56
+ * saveChanges('He');
57
+ * saveChanges('Hello'); // Only this will execute after 1 second
58
+ *
59
+ * @example
60
+ * // Search input debouncing
61
+ * const searchInput = document.getElementById('search');
62
+ * const performSearch = debounce((query: string) => {
63
+ * fetch(`/api/search?q=${query}`)
64
+ * .then(res => res.json())
65
+ * .then(results => displayResults(results));
66
+ * }, 300);
67
+ *
68
+ * searchInput.addEventListener('input', (e) => {
69
+ * performSearch(e.target.value);
70
+ * });
71
+ *
72
+ * @example
73
+ * // Window resize handler
74
+ * const handleResize = debounce(() => {
75
+ * const width = window.innerWidth;
76
+ * const height = window.innerHeight;
77
+ * console.log(`Resized to ${width}x${height}`);
78
+ * recalculateLayout();
79
+ * }, 250);
80
+ *
81
+ * window.addEventListener('resize', handleResize);
82
+ *
83
+ * @see throttle - Limit execution rate without delaying
84
+ * @since 2025-07-03
85
+ */
86
+ export declare const debounce: <T extends any[]>(fn: (...args: T) => void, delay: number) => ((...args: T) => void);
87
+ /**
88
+ * Throttle function execution.
89
+ * @description Ensures the function is called at most once per specified time period.
90
+ * Unlike debounce, throttle guarantees regular execution for continuous events.
91
+ * The first call is executed immediately, then subsequent calls are rate-limited.
92
+ *
93
+ * @template T - The types of the function arguments
94
+ * @param {function(...T): void} fn - The function to throttle
95
+ * @param {number} delay - The minimum delay between calls in milliseconds
96
+ * @returns {function(...T): void} The throttled function
97
+ *
98
+ * @category Timing
99
+ * @example
100
+ * // Basic throttle
101
+ * const logScroll = throttle(() => {
102
+ * console.log('Scroll position:', window.scrollY);
103
+ * }, 100);
104
+ *
105
+ * window.addEventListener('scroll', logScroll);
106
+ * // Logs at most once every 100ms during scrolling
107
+ *
108
+ * @example
109
+ * // API rate limiting
110
+ * const trackEvent = throttle((event: string, data: any) => {
111
+ * fetch('/api/analytics', {
112
+ * method: 'POST',
113
+ * body: JSON.stringify({ event, data, timestamp: Date.now() })
114
+ * });
115
+ * }, 1000);
116
+ *
117
+ * // Won't exceed 1 request per second
118
+ * button.addEventListener('click', () => trackEvent('button_click', { id: 'submit' }));
119
+ *
120
+ * @example
121
+ * // Game loop or animation
122
+ * const updateGame = throttle(() => {
123
+ * player.updatePosition();
124
+ * enemies.forEach(e => e.update());
125
+ * renderer.draw();
126
+ * }, 16); // ~60 FPS
127
+ *
128
+ * setInterval(updateGame, 0);
129
+ *
130
+ * @see debounce - Delay execution until activity stops
131
+ * @since 2025-07-03
132
+ */
133
+ export declare const throttle: <T extends any[], R>(fn: (...args: T) => R, limit: number) => ((...args: T) => R | undefined);
134
+ /**
135
+ * Batch async operations to avoid overwhelming external services.
136
+ * @description Processes items in chunks with optional delays between batches.
137
+ * Essential for rate-limited APIs or resource-intensive operations.
138
+ * Executes operations in parallel within each batch but sequential between batches.
139
+ *
140
+ * @template T - The type of items to process
141
+ * @template R - The type of results
142
+ * @param {T[]} items - Array of items to process
143
+ * @param {function(T): Promise<R>} fn - Async function to process each item
144
+ * @param {number} batchSize - Maximum number of items to process in parallel
145
+ * @param {number} [delayMs=0] - Delay in milliseconds between batches
146
+ * @returns {Promise<R[]>} Array of results in the same order as input
147
+ *
148
+ * @category Batching
149
+ * @example
150
+ * // Basic batch processing
151
+ * const userIds = Array.from({ length: 100 }, (_, i) => i + 1);
152
+ * const fetchUser = async (id: number) => {
153
+ * const res = await fetch(`/api/users/${id}`);
154
+ * return res.json();
155
+ * };
156
+ *
157
+ * const users = await batchAsync(userIds, fetchUser, 10, 100);
158
+ * // Fetches 10 users at a time with 100ms delay between batches
159
+ *
160
+ * @example
161
+ * // Email sending with rate limits
162
+ * const recipients = [
163
+ * { email: 'user1@example.com', name: 'User 1' },
164
+ * { email: 'user2@example.com', name: 'User 2' },
165
+ * // ... many more
166
+ * ];
167
+ *
168
+ * const sendEmail = async (recipient: typeof recipients[0]) => {
169
+ * return await emailService.send({
170
+ * to: recipient.email,
171
+ * subject: 'Newsletter',
172
+ * body: `Hello ${recipient.name}!`
173
+ * });
174
+ * };
175
+ *
176
+ * // Send 20 emails per batch with 1 second delay (rate limit compliance)
177
+ * const results = await batchAsync(recipients, sendEmail, 20, 1000);
178
+ *
179
+ * @example
180
+ * // Image processing
181
+ * const imageUrls = ['img1.jpg', 'img2.jpg', // ... more images, 'img100.jpg'];
182
+ *
183
+ * const processImage = async (url: string) => {
184
+ * const img = await loadImage(url);
185
+ * const processed = await applyFilters(img);
186
+ * return await saveImage(processed);
187
+ * };
188
+ *
189
+ * // Process 5 images at a time to avoid memory issues
190
+ * const processed = await batchAsync(imageUrls, processImage, 5, 200);
191
+ * console.log(`Processed ${processed.length} images`);
192
+ *
193
+ * @see Promise.all - Process all items concurrently without batching
194
+ */
195
+ export declare const batchAsync: <T, U>(items: T[], fn: (item: T) => Promise<U>, batchSize?: number, delayMs?: number) => Promise<U[]>;
196
+ /**
197
+ * Advanced timing utilities for specialized use cases.
198
+ *
199
+ * @category Advanced
200
+ */
201
+ export declare const timingUtils: {
202
+ /**
203
+ * Debounce with immediate option.
204
+ * Optionally invokes the function immediately on the leading edge.
205
+ *
206
+ * @example
207
+ * // Execute immediately on first call, then debounce
208
+ * const saveWithFeedback = timingUtils.debounceWithImmediate(
209
+ * (data: string) => {
210
+ * showSaveIndicator();
211
+ * saveToServer(data);
212
+ * },
213
+ * 1000,
214
+ * true // immediate
215
+ * );
216
+ *
217
+ * // First call executes immediately, subsequent calls are debounced
218
+ * saveWithFeedback('data1'); // Executes immediately
219
+ * saveWithFeedback('data2'); // Debounced
220
+ * saveWithFeedback('data3'); // Debounced, only this executes after 1s
221
+ */
222
+ debounceWithImmediate: <T extends any[]>(fn: (...args: T) => void, delay: number, immediate?: boolean) => ((...args: T) => void);
223
+ /**
224
+ * Throttle with trailing call option.
225
+ * Ensures the last call is always executed.
226
+ *
227
+ * @example
228
+ * // Progress updates with final state guarantee
229
+ * const updateProgress = timingUtils.throttleWithTrailing(
230
+ * (percent: number) => {
231
+ * progressBar.style.width = `${percent}%`;
232
+ * if (percent === 100) {
233
+ * showCompletionMessage();
234
+ * }
235
+ * },
236
+ * 100,
237
+ * true // trailing
238
+ * );
239
+ *
240
+ * // Updates at most every 100ms, but guarantees the final 100% is shown
241
+ * for (let i = 0; i <= 100; i++) {
242
+ * updateProgress(i);
243
+ * }
244
+ */
245
+ throttleWithTrailing: <T extends any[]>(fn: (...args: T) => void, limit: number, trailing?: boolean) => ((...args: T) => void);
246
+ /**
247
+ * Create a function that measures its execution time.
248
+ *
249
+ * @example
250
+ * const timedFetch = timingUtils.measureTime(
251
+ * async (url: string) => {
252
+ * const response = await fetch(url);
253
+ * return response.json();
254
+ * },
255
+ * (duration, result) => {
256
+ * console.log(`Fetch took ${duration}ms`);
257
+ * analytics.track('api_call_duration', { duration, url: result.url });
258
+ * }
259
+ * );
260
+ *
261
+ * const data = await timedFetch('/api/data');
262
+ */
263
+ measureTime: <T extends unknown[], R>(fn: (...args: T) => R, onComplete?: (duration: number, result: Awaited<R>) => void) => ((...args: T) => R);
264
+ };
265
+ //# sourceMappingURL=performance.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance.d.mts","sourceRoot":"","sources":["../src/performance.mts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,eAAO,MAAM,QAAQ,GAAI,CAAC,SAAS,GAAG,EAAE,MAClC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,SACjB,MAAM,KACZ,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,CAOvB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,eAAO,MAAM,QAAQ,GAAI,CAAC,SAAS,GAAG,EAAE,EAAE,CAAC,MACrC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,SACd,MAAM,KACZ,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,SAAS,CAahC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,eAAO,MAAM,UAAU,GAAU,CAAC,EAAE,CAAC,SAC5B,CAAC,EAAE,MACN,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,2CAG1B,OAAO,CAAC,CAAC,EAAE,CAeb,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW;IACtB;;;;;;;;;;;;;;;;;;;OAmBG;4BAEqB,CAAC,SAAS,GAAG,EAAE,MACjC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,SACjB,MAAM,0BAEZ,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAuBzB;;;;;;;;;;;;;;;;;;;;;OAqBG;2BAEoB,CAAC,SAAS,GAAG,EAAE,MAChC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,SACjB,MAAM,yBAEZ,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IA+BzB;;;;;;;;;;;;;;;;OAgBG;kBACW,CAAC,SAAS,OAAO,EAAE,EAAE,CAAC,MAC9B,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,eACR,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,KAC1D,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;CAuBvB,CAAC"}