@procedures/collections 0.46.0 → 0.47.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 (233) hide show
  1. package/CHANGELOG.md +42 -8
  2. package/README.md +30 -0
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/index.d.ts +1 -58
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +3 -94
  7. package/dist/index.js.map +1 -1
  8. package/dist/storage/index.d.ts +2 -2
  9. package/dist/storage/index.d.ts.map +1 -1
  10. package/dist/storage/index.js +1 -1
  11. package/dist/storage/index.js.map +1 -1
  12. package/dist/storage/memory.d.ts +1 -1
  13. package/dist/storage/memory.d.ts.map +1 -1
  14. package/dist/storage/memory.js +1 -1
  15. package/dist/storage/memory.js.map +1 -1
  16. package/dist/testing/index.d.ts +1 -1
  17. package/dist/testing/index.d.ts.map +1 -1
  18. package/dist/testing/index.js +1 -1
  19. package/dist/testing/index.js.map +1 -1
  20. package/dist/testing/storage-contract.js +1 -1
  21. package/dist/testing/storage-contract.js.map +1 -1
  22. package/dist/undo/index.d.ts +1 -1
  23. package/dist/undo/index.js +1 -1
  24. package/dist/undo/undo-log.d.ts +1 -1
  25. package/dist/undo/undo-log.js +1 -1
  26. package/package.json +6 -6
  27. package/src/index.ts +338 -213
  28. package/src/storage/index.ts +2 -2
  29. package/src/storage/memory.ts +1 -1
  30. package/src/testing/index.ts +1 -1
  31. package/src/testing/storage-contract.ts +1 -1
  32. package/src/undo/index.ts +1 -1
  33. package/src/undo/undo-log.ts +1 -1
  34. package/dist/async/async-queue.d.ts +0 -170
  35. package/dist/async/async-queue.d.ts.map +0 -1
  36. package/dist/async/async-queue.js +0 -404
  37. package/dist/async/async-queue.js.map +0 -1
  38. package/dist/async/channels.d.ts +0 -211
  39. package/dist/async/channels.d.ts.map +0 -1
  40. package/dist/async/channels.js +0 -393
  41. package/dist/async/channels.js.map +0 -1
  42. package/dist/async/settled.d.ts +0 -23
  43. package/dist/async/settled.d.ts.map +0 -1
  44. package/dist/async/settled.js +0 -32
  45. package/dist/async/settled.js.map +0 -1
  46. package/dist/behaviors/bounded.d.ts +0 -79
  47. package/dist/behaviors/bounded.d.ts.map +0 -1
  48. package/dist/behaviors/bounded.js +0 -393
  49. package/dist/behaviors/bounded.js.map +0 -1
  50. package/dist/behaviors/composite.d.ts +0 -17
  51. package/dist/behaviors/composite.d.ts.map +0 -1
  52. package/dist/behaviors/composite.js +0 -93
  53. package/dist/behaviors/composite.js.map +0 -1
  54. package/dist/behaviors/evented.d.ts +0 -154
  55. package/dist/behaviors/evented.d.ts.map +0 -1
  56. package/dist/behaviors/evented.js +0 -299
  57. package/dist/behaviors/evented.js.map +0 -1
  58. package/dist/behaviors/lru.d.ts +0 -84
  59. package/dist/behaviors/lru.d.ts.map +0 -1
  60. package/dist/behaviors/lru.js +0 -376
  61. package/dist/behaviors/lru.js.map +0 -1
  62. package/dist/behaviors/readonly.d.ts +0 -73
  63. package/dist/behaviors/readonly.d.ts.map +0 -1
  64. package/dist/behaviors/readonly.js +0 -189
  65. package/dist/behaviors/readonly.js.map +0 -1
  66. package/dist/behaviors/safe.d.ts +0 -163
  67. package/dist/behaviors/safe.d.ts.map +0 -1
  68. package/dist/behaviors/safe.js +0 -176
  69. package/dist/behaviors/safe.js.map +0 -1
  70. package/dist/behaviors/synchronized.d.ts +0 -88
  71. package/dist/behaviors/synchronized.d.ts.map +0 -1
  72. package/dist/behaviors/synchronized.js +0 -285
  73. package/dist/behaviors/synchronized.js.map +0 -1
  74. package/dist/behaviors/ttl.d.ts +0 -118
  75. package/dist/behaviors/ttl.d.ts.map +0 -1
  76. package/dist/behaviors/ttl.js +0 -354
  77. package/dist/behaviors/ttl.js.map +0 -1
  78. package/dist/contracts/model.d.ts +0 -29
  79. package/dist/contracts/model.d.ts.map +0 -1
  80. package/dist/contracts/model.js +0 -26
  81. package/dist/contracts/model.js.map +0 -1
  82. package/dist/core/effects.d.ts +0 -176
  83. package/dist/core/effects.d.ts.map +0 -1
  84. package/dist/core/effects.js +0 -180
  85. package/dist/core/effects.js.map +0 -1
  86. package/dist/core/events.d.ts +0 -192
  87. package/dist/core/events.d.ts.map +0 -1
  88. package/dist/core/events.js +0 -291
  89. package/dist/core/events.js.map +0 -1
  90. package/dist/core/middleware.d.ts +0 -231
  91. package/dist/core/middleware.d.ts.map +0 -1
  92. package/dist/core/middleware.js +0 -161
  93. package/dist/core/middleware.js.map +0 -1
  94. package/dist/core/policies.d.ts +0 -220
  95. package/dist/core/policies.d.ts.map +0 -1
  96. package/dist/core/policies.js +0 -48
  97. package/dist/core/policies.js.map +0 -1
  98. package/dist/core/traits.d.ts +0 -142
  99. package/dist/core/traits.d.ts.map +0 -1
  100. package/dist/core/traits.js +0 -8
  101. package/dist/core/traits.js.map +0 -1
  102. package/dist/fx/collectors.d.ts +0 -193
  103. package/dist/fx/collectors.d.ts.map +0 -1
  104. package/dist/fx/collectors.js +0 -375
  105. package/dist/fx/collectors.js.map +0 -1
  106. package/dist/fx/iter.d.ts +0 -166
  107. package/dist/fx/iter.d.ts.map +0 -1
  108. package/dist/fx/iter.js +0 -421
  109. package/dist/fx/iter.js.map +0 -1
  110. package/dist/impl/array-deque.d.ts +0 -112
  111. package/dist/impl/array-deque.d.ts.map +0 -1
  112. package/dist/impl/array-deque.js +0 -380
  113. package/dist/impl/array-deque.js.map +0 -1
  114. package/dist/impl/array-list.d.ts +0 -101
  115. package/dist/impl/array-list.d.ts.map +0 -1
  116. package/dist/impl/array-list.js +0 -387
  117. package/dist/impl/array-list.js.map +0 -1
  118. package/dist/impl/hash-map.d.ts +0 -149
  119. package/dist/impl/hash-map.d.ts.map +0 -1
  120. package/dist/impl/hash-map.js +0 -473
  121. package/dist/impl/hash-map.js.map +0 -1
  122. package/dist/impl/hash-set.d.ts +0 -125
  123. package/dist/impl/hash-set.d.ts.map +0 -1
  124. package/dist/impl/hash-set.js +0 -264
  125. package/dist/impl/hash-set.js.map +0 -1
  126. package/dist/impl/linked-hash-map.d.ts +0 -141
  127. package/dist/impl/linked-hash-map.d.ts.map +0 -1
  128. package/dist/impl/linked-hash-map.js +0 -442
  129. package/dist/impl/linked-hash-map.js.map +0 -1
  130. package/dist/impl/linked-list.d.ts +0 -109
  131. package/dist/impl/linked-list.d.ts.map +0 -1
  132. package/dist/impl/linked-list.js +0 -494
  133. package/dist/impl/linked-list.js.map +0 -1
  134. package/dist/impl/priority-queue.d.ts +0 -139
  135. package/dist/impl/priority-queue.d.ts.map +0 -1
  136. package/dist/impl/priority-queue.js +0 -343
  137. package/dist/impl/priority-queue.js.map +0 -1
  138. package/dist/impl/tree-map.d.ts +0 -153
  139. package/dist/impl/tree-map.d.ts.map +0 -1
  140. package/dist/impl/tree-map.js +0 -788
  141. package/dist/impl/tree-map.js.map +0 -1
  142. package/dist/impl/tree-set.d.ts +0 -112
  143. package/dist/impl/tree-set.d.ts.map +0 -1
  144. package/dist/impl/tree-set.js +0 -374
  145. package/dist/impl/tree-set.js.map +0 -1
  146. package/dist/interfaces/collection.d.ts +0 -119
  147. package/dist/interfaces/collection.d.ts.map +0 -1
  148. package/dist/interfaces/collection.js +0 -8
  149. package/dist/interfaces/collection.js.map +0 -1
  150. package/dist/interfaces/list.d.ts +0 -247
  151. package/dist/interfaces/list.d.ts.map +0 -1
  152. package/dist/interfaces/list.js +0 -8
  153. package/dist/interfaces/list.js.map +0 -1
  154. package/dist/interfaces/map.d.ts +0 -344
  155. package/dist/interfaces/map.d.ts.map +0 -1
  156. package/dist/interfaces/map.js +0 -8
  157. package/dist/interfaces/map.js.map +0 -1
  158. package/dist/interfaces/queue.d.ts +0 -304
  159. package/dist/interfaces/queue.d.ts.map +0 -1
  160. package/dist/interfaces/queue.js +0 -8
  161. package/dist/interfaces/queue.js.map +0 -1
  162. package/dist/interfaces/set.d.ts +0 -137
  163. package/dist/interfaces/set.d.ts.map +0 -1
  164. package/dist/interfaces/set.js +0 -8
  165. package/dist/interfaces/set.js.map +0 -1
  166. package/dist/order/index.d.ts +0 -7
  167. package/dist/order/index.d.ts.map +0 -1
  168. package/dist/order/index.js +0 -7
  169. package/dist/order/index.js.map +0 -1
  170. package/dist/order/rank.d.ts +0 -100
  171. package/dist/order/rank.d.ts.map +0 -1
  172. package/dist/order/rank.js +0 -286
  173. package/dist/order/rank.js.map +0 -1
  174. package/dist/storage/listeners.d.ts +0 -39
  175. package/dist/storage/listeners.d.ts.map +0 -1
  176. package/dist/storage/listeners.js +0 -65
  177. package/dist/storage/listeners.js.map +0 -1
  178. package/dist/testing/check.d.ts +0 -25
  179. package/dist/testing/check.d.ts.map +0 -1
  180. package/dist/testing/check.js +0 -85
  181. package/dist/testing/check.js.map +0 -1
  182. package/dist/utils/defaults.d.ts +0 -135
  183. package/dist/utils/defaults.d.ts.map +0 -1
  184. package/dist/utils/defaults.js +0 -322
  185. package/dist/utils/defaults.js.map +0 -1
  186. package/dist/utils/factories.d.ts +0 -144
  187. package/dist/utils/factories.d.ts.map +0 -1
  188. package/dist/utils/factories.js +0 -293
  189. package/dist/utils/factories.js.map +0 -1
  190. package/dist/utils/helpers.d.ts +0 -137
  191. package/dist/utils/helpers.d.ts.map +0 -1
  192. package/dist/utils/helpers.js +0 -221
  193. package/dist/utils/helpers.js.map +0 -1
  194. package/src/async/async-queue.ts +0 -481
  195. package/src/async/channels.ts +0 -450
  196. package/src/async/settled.ts +0 -41
  197. package/src/behaviors/bounded.ts +0 -485
  198. package/src/behaviors/composite.ts +0 -99
  199. package/src/behaviors/evented.ts +0 -464
  200. package/src/behaviors/lru.ts +0 -447
  201. package/src/behaviors/readonly.ts +0 -236
  202. package/src/behaviors/safe.ts +0 -372
  203. package/src/behaviors/synchronized.ts +0 -316
  204. package/src/behaviors/ttl.ts +0 -462
  205. package/src/contracts/model.ts +0 -44
  206. package/src/core/effects.ts +0 -323
  207. package/src/core/events.ts +0 -356
  208. package/src/core/middleware.ts +0 -415
  209. package/src/core/policies.ts +0 -316
  210. package/src/core/traits.ts +0 -164
  211. package/src/fx/collectors.ts +0 -500
  212. package/src/fx/iter.ts +0 -536
  213. package/src/impl/array-deque.ts +0 -463
  214. package/src/impl/array-list.ts +0 -490
  215. package/src/impl/hash-map.ts +0 -623
  216. package/src/impl/hash-set.ts +0 -342
  217. package/src/impl/linked-hash-map.ts +0 -572
  218. package/src/impl/linked-list.ts +0 -606
  219. package/src/impl/priority-queue.ts +0 -448
  220. package/src/impl/tree-map.ts +0 -912
  221. package/src/impl/tree-set.ts +0 -469
  222. package/src/interfaces/collection.ts +0 -141
  223. package/src/interfaces/list.ts +0 -281
  224. package/src/interfaces/map.ts +0 -405
  225. package/src/interfaces/queue.ts +0 -353
  226. package/src/interfaces/set.ts +0 -158
  227. package/src/order/index.ts +0 -6
  228. package/src/order/rank.ts +0 -271
  229. package/src/storage/listeners.ts +0 -72
  230. package/src/testing/check.ts +0 -81
  231. package/src/utils/defaults.ts +0 -345
  232. package/src/utils/factories.ts +0 -357
  233. package/src/utils/helpers.ts +0 -248
package/src/fx/iter.ts DELETED
@@ -1,536 +0,0 @@
1
- /**
2
- * Functional operations for iterables (lazy sync transforms).
3
- *
4
- * Provides Stream-like operations with lazy evaluation.
5
- * All operations return generators for composability.
6
- *
7
- * @example
8
- * const result = pipe(
9
- * [1, 2, 3, 4, 5],
10
- * map(x => x * 2),
11
- * filter(x => x > 5),
12
- * take(2),
13
- * toArray
14
- * ) // [6, 8]
15
- */
16
-
17
- // ============================================================================
18
- // Mapping and transformation
19
- // ============================================================================
20
-
21
- /**
22
- * Maps each element through a function.
23
- *
24
- * @example
25
- * const doubled = map([1, 2, 3], x => x * 2) // [2, 4, 6]
26
- */
27
- export function* map<T, U>(
28
- iterable: Iterable<T>,
29
- fn: (value: T, index: number) => U
30
- ): Generator<U> {
31
- let index = 0;
32
- for (const value of iterable) {
33
- yield fn(value, index++);
34
- }
35
- }
36
-
37
- /**
38
- * Filters elements based on a predicate.
39
- */
40
- export function* filter<T>(
41
- iterable: Iterable<T>,
42
- predicate: (value: T, index: number) => boolean
43
- ): Generator<T> {
44
- let index = 0;
45
- for (const value of iterable) {
46
- if (predicate(value, index++)) {
47
- yield value;
48
- }
49
- }
50
- }
51
-
52
- /**
53
- * FlatMaps each element to an iterable and flattens.
54
- */
55
- export function* flatMap<T, U>(
56
- iterable: Iterable<T>,
57
- fn: (value: T, index: number) => Iterable<U>
58
- ): Generator<U> {
59
- let index = 0;
60
- for (const value of iterable) {
61
- yield* fn(value, index++);
62
- }
63
- }
64
-
65
- /**
66
- * Flattens a nested iterable.
67
- */
68
- export function* flatten<T>(iterable: Iterable<Iterable<T>>): Generator<T> {
69
- for (const inner of iterable) {
70
- yield* inner;
71
- }
72
- }
73
-
74
- // ============================================================================
75
- // Limiting and skipping
76
- // ============================================================================
77
-
78
- /**
79
- * Takes the first n elements.
80
- */
81
- export function* take<T>(iterable: Iterable<T>, n: number): Generator<T> {
82
- let count = 0;
83
- for (const value of iterable) {
84
- if (count++ >= n) break;
85
- yield value;
86
- }
87
- }
88
-
89
- /**
90
- * Skips the first n elements.
91
- */
92
- export function* skip<T>(iterable: Iterable<T>, n: number): Generator<T> {
93
- let count = 0;
94
- for (const value of iterable) {
95
- if (count++ >= n) {
96
- yield value;
97
- }
98
- }
99
- }
100
-
101
- /**
102
- * Takes elements while predicate is true.
103
- */
104
- export function* takeWhile<T>(
105
- iterable: Iterable<T>,
106
- predicate: (value: T) => boolean
107
- ): Generator<T> {
108
- for (const value of iterable) {
109
- if (!predicate(value)) break;
110
- yield value;
111
- }
112
- }
113
-
114
- /**
115
- * Skips elements while predicate is true.
116
- */
117
- export function* skipWhile<T>(
118
- iterable: Iterable<T>,
119
- predicate: (value: T) => boolean
120
- ): Generator<T> {
121
- let skipping = true;
122
- for (const value of iterable) {
123
- if (skipping && predicate(value)) continue;
124
- skipping = false;
125
- yield value;
126
- }
127
- }
128
-
129
- // ============================================================================
130
- // Combining
131
- // ============================================================================
132
-
133
- /**
134
- * Concatenates multiple iterables.
135
- */
136
- export function* concat<T>(...iterables: Iterable<T>[]): Generator<T> {
137
- for (const iterable of iterables) {
138
- yield* iterable;
139
- }
140
- }
141
-
142
- /**
143
- * Zips multiple iterables together.
144
- */
145
- export function* zip<T extends any[]>(
146
- ...iterables: { [K in keyof T]: Iterable<T[K]> }
147
- ): Generator<T> {
148
- const iterators = iterables.map((it) => it[Symbol.iterator]());
149
-
150
- while (true) {
151
- const results = iterators.map((it) => it.next());
152
- if (results.some((r) => r.done)) break;
153
- yield results.map((r) => r.value) as T;
154
- }
155
- }
156
-
157
- /**
158
- * Zips with index.
159
- */
160
- export function* enumerate<T>(iterable: Iterable<T>): Generator<[number, T]> {
161
- let index = 0;
162
- for (const value of iterable) {
163
- yield [index++, value];
164
- }
165
- }
166
-
167
- // ============================================================================
168
- // Partitioning
169
- // ============================================================================
170
-
171
- /**
172
- * Chunks elements into arrays of specified size.
173
- */
174
- export function* chunk<T>(iterable: Iterable<T>, size: number): Generator<T[]> {
175
- let chunk: T[] = [];
176
- for (const value of iterable) {
177
- chunk.push(value);
178
- if (chunk.length === size) {
179
- yield chunk;
180
- chunk = [];
181
- }
182
- }
183
- if (chunk.length > 0) {
184
- yield chunk;
185
- }
186
- }
187
-
188
- /**
189
- * Creates a sliding window of specified size.
190
- */
191
- export function* window<T>(iterable: Iterable<T>, size: number): Generator<T[]> {
192
- const window: T[] = [];
193
- for (const value of iterable) {
194
- window.push(value);
195
- if (window.length > size) {
196
- window.shift();
197
- }
198
- if (window.length === size) {
199
- yield [...window];
200
- }
201
- }
202
- }
203
-
204
- /**
205
- * Partitions elements into two arrays based on predicate.
206
- */
207
- export function partition<T>(
208
- iterable: Iterable<T>,
209
- predicate: (value: T) => boolean
210
- ): [T[], T[]] {
211
- const truthy: T[] = [];
212
- const falsy: T[] = [];
213
-
214
- for (const value of iterable) {
215
- if (predicate(value)) {
216
- truthy.push(value);
217
- } else {
218
- falsy.push(value);
219
- }
220
- }
221
-
222
- return [truthy, falsy];
223
- }
224
-
225
- // ============================================================================
226
- // Reducing and folding
227
- // ============================================================================
228
-
229
- /**
230
- * Reduces iterable to a single value.
231
- */
232
- export function reduce<T, U>(
233
- iterable: Iterable<T>,
234
- fn: (acc: U, value: T, index: number) => U,
235
- initial: U
236
- ): U {
237
- let acc = initial;
238
- let index = 0;
239
- for (const value of iterable) {
240
- acc = fn(acc, value, index++);
241
- }
242
- return acc;
243
- }
244
-
245
- /**
246
- * Scans (like reduce but emits intermediate results).
247
- */
248
- export function* scan<T, U>(
249
- iterable: Iterable<T>,
250
- fn: (acc: U, value: T) => U,
251
- initial: U
252
- ): Generator<U> {
253
- let acc = initial;
254
- yield acc;
255
- for (const value of iterable) {
256
- acc = fn(acc, value);
257
- yield acc;
258
- }
259
- }
260
-
261
- // ============================================================================
262
- // Sorting and ordering
263
- // ============================================================================
264
-
265
- /**
266
- * Sorts elements (materializes the iterable).
267
- */
268
- export function* sort<T>(
269
- iterable: Iterable<T>,
270
- compare?: (a: T, b: T) => number
271
- ): Generator<T> {
272
- const array = Array.from(iterable);
273
- array.sort(compare);
274
- yield* array;
275
- }
276
-
277
- /**
278
- * Reverses elements (materializes the iterable).
279
- */
280
- export function* reverse<T>(iterable: Iterable<T>): Generator<T> {
281
- const array = Array.from(iterable);
282
- array.reverse();
283
- yield* array;
284
- }
285
-
286
- // ============================================================================
287
- // Distinct and uniqueness
288
- // ============================================================================
289
-
290
- /**
291
- * Removes duplicate elements (by reference or key function).
292
- */
293
- export function* distinct<T, K = T>(
294
- iterable: Iterable<T>,
295
- keyFn?: (value: T) => K
296
- ): Generator<T> {
297
- const seen = new Set<K>();
298
- for (const value of iterable) {
299
- const key = (keyFn ? keyFn(value) : value) as K;
300
- if (!seen.has(key)) {
301
- seen.add(key);
302
- yield value;
303
- }
304
- }
305
- }
306
-
307
- /**
308
- * Removes consecutive duplicates.
309
- */
310
- export function* distinctConsecutive<T, K = T>(
311
- iterable: Iterable<T>,
312
- keyFn?: (value: T) => K
313
- ): Generator<T> {
314
- let lastKey: K | undefined;
315
- let first = true;
316
-
317
- for (const value of iterable) {
318
- const key = (keyFn ? keyFn(value) : value) as K;
319
- if (first || key !== lastKey) {
320
- yield value;
321
- lastKey = key;
322
- first = false;
323
- }
324
- }
325
- }
326
-
327
- // ============================================================================
328
- // Peeking and side effects
329
- // ============================================================================
330
-
331
- /**
332
- * Performs a side effect for each element without modifying the stream.
333
- */
334
- export function* tap<T>(
335
- iterable: Iterable<T>,
336
- fn: (value: T, index: number) => void
337
- ): Generator<T> {
338
- let index = 0;
339
- for (const value of iterable) {
340
- fn(value, index++);
341
- yield value;
342
- }
343
- }
344
-
345
- // ============================================================================
346
- // Predicates and checks
347
- // ============================================================================
348
-
349
- /**
350
- * Returns true if any element matches the predicate.
351
- */
352
- export function some<T>(
353
- iterable: Iterable<T>,
354
- predicate: (value: T) => boolean
355
- ): boolean {
356
- for (const value of iterable) {
357
- if (predicate(value)) return true;
358
- }
359
- return false;
360
- }
361
-
362
- /**
363
- * Returns true if all elements match the predicate.
364
- */
365
- export function every<T>(
366
- iterable: Iterable<T>,
367
- predicate: (value: T) => boolean
368
- ): boolean {
369
- for (const value of iterable) {
370
- if (!predicate(value)) return false;
371
- }
372
- return true;
373
- }
374
-
375
- /**
376
- * Returns true if no elements match the predicate.
377
- */
378
- export function none<T>(
379
- iterable: Iterable<T>,
380
- predicate: (value: T) => boolean
381
- ): boolean {
382
- return !some(iterable, predicate);
383
- }
384
-
385
- /**
386
- * Finds the first element matching the predicate.
387
- */
388
- export function find<T>(
389
- iterable: Iterable<T>,
390
- predicate: (value: T) => boolean
391
- ): T | undefined {
392
- for (const value of iterable) {
393
- if (predicate(value)) return value;
394
- }
395
- return undefined;
396
- }
397
-
398
- /**
399
- * Counts elements (optionally matching a predicate).
400
- */
401
- export function count<T>(
402
- iterable: Iterable<T>,
403
- predicate?: (value: T) => boolean
404
- ): number {
405
- let count = 0;
406
- for (const value of iterable) {
407
- if (!predicate || predicate(value)) {
408
- count++;
409
- }
410
- }
411
- return count;
412
- }
413
-
414
- // ============================================================================
415
- // Min/Max
416
- // ============================================================================
417
-
418
- /**
419
- * Returns the minimum element.
420
- */
421
- export function min<T>(
422
- iterable: Iterable<T>,
423
- compare?: (a: T, b: T) => number
424
- ): T | undefined {
425
- const cmp = compare || ((a: any, b: any) => a - b);
426
- let minValue: T | undefined;
427
-
428
- for (const value of iterable) {
429
- if (minValue === undefined || cmp(value, minValue) < 0) {
430
- minValue = value;
431
- }
432
- }
433
-
434
- return minValue;
435
- }
436
-
437
- /**
438
- * Returns the maximum element.
439
- */
440
- export function max<T>(
441
- iterable: Iterable<T>,
442
- compare?: (a: T, b: T) => number
443
- ): T | undefined {
444
- const cmp = compare || ((a: any, b: any) => a - b);
445
- let maxValue: T | undefined;
446
-
447
- for (const value of iterable) {
448
- if (maxValue === undefined || cmp(value, maxValue) > 0) {
449
- maxValue = value;
450
- }
451
- }
452
-
453
- return maxValue;
454
- }
455
-
456
- /**
457
- * Returns the sum of elements.
458
- */
459
- export function sum(iterable: Iterable<number>): number {
460
- let total = 0;
461
- for (const value of iterable) {
462
- total += value;
463
- }
464
- return total;
465
- }
466
-
467
- /**
468
- * Returns the average of elements.
469
- */
470
- export function average(iterable: Iterable<number>): number | undefined {
471
- let total = 0;
472
- let count = 0;
473
-
474
- for (const value of iterable) {
475
- total += value;
476
- count++;
477
- }
478
-
479
- return count === 0 ? undefined : total / count;
480
- }
481
-
482
- // ============================================================================
483
- // Terminal operations (materialization)
484
- // ============================================================================
485
-
486
- /**
487
- * Collects elements into an array.
488
- */
489
- export function toArray<T>(iterable: Iterable<T>): T[] {
490
- return Array.from(iterable);
491
- }
492
-
493
- /**
494
- * Collects elements into a Set.
495
- */
496
- export function toSet<T>(iterable: Iterable<T>): Set<T> {
497
- return new Set(iterable);
498
- }
499
-
500
- /**
501
- * Collects elements into a Map.
502
- */
503
- export function toMap<T, K, V>(
504
- iterable: Iterable<T>,
505
- keyFn: (value: T) => K,
506
- valueFn: (value: T) => V
507
- ): Map<K, V> {
508
- const map = new Map<K, V>();
509
- for (const value of iterable) {
510
- map.set(keyFn(value), valueFn(value));
511
- }
512
- return map;
513
- }
514
-
515
- // ============================================================================
516
- // Pipe utility for composition
517
- // ============================================================================
518
-
519
- /**
520
- * Pipes a value through a series of transformations.
521
- *
522
- * @example
523
- * const result = pipe(
524
- * [1, 2, 3, 4, 5],
525
- * (it) => map(it, x => x * 2),
526
- * (it) => filter(it, x => x > 5),
527
- * (it) => take(it, 2),
528
- * toArray
529
- * ) // [6, 8]
530
- */
531
- export function pipe<T>(
532
- value: T,
533
- ...fns: Array<(value: any) => any>
534
- ): any {
535
- return fns.reduce((acc, fn) => fn(acc), value);
536
- }