functional-examples 0.0.0-alpha.1

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 (202) hide show
  1. package/README.md +148 -0
  2. package/dist/cli/commands/generate.d.ts +10 -0
  3. package/dist/cli/commands/generate.d.ts.map +1 -0
  4. package/dist/cli/commands/generate.js +64 -0
  5. package/dist/cli/commands/generate.js.map +1 -0
  6. package/dist/cli/commands/init.d.ts +14 -0
  7. package/dist/cli/commands/init.d.ts.map +1 -0
  8. package/dist/cli/commands/init.js +95 -0
  9. package/dist/cli/commands/init.js.map +1 -0
  10. package/dist/cli/commands/scan.d.ts +20 -0
  11. package/dist/cli/commands/scan.d.ts.map +1 -0
  12. package/dist/cli/commands/scan.js +182 -0
  13. package/dist/cli/commands/scan.js.map +1 -0
  14. package/dist/cli/commands/validate.d.ts +10 -0
  15. package/dist/cli/commands/validate.d.ts.map +1 -0
  16. package/dist/cli/commands/validate.js +65 -0
  17. package/dist/cli/commands/validate.js.map +1 -0
  18. package/dist/cli/index.d.ts +88 -0
  19. package/dist/cli/index.d.ts.map +1 -0
  20. package/dist/cli/index.js +43 -0
  21. package/dist/cli/index.js.map +1 -0
  22. package/dist/cli/plugin-commands.d.ts +17 -0
  23. package/dist/cli/plugin-commands.d.ts.map +1 -0
  24. package/dist/cli/plugin-commands.js +45 -0
  25. package/dist/cli/plugin-commands.js.map +1 -0
  26. package/dist/config/index.d.ts +11 -0
  27. package/dist/config/index.d.ts.map +1 -0
  28. package/dist/config/index.js +9 -0
  29. package/dist/config/index.js.map +1 -0
  30. package/dist/config/index.spec.d.ts +5 -0
  31. package/dist/config/index.spec.d.ts.map +1 -0
  32. package/dist/config/index.spec.js +142 -0
  33. package/dist/config/index.spec.js.map +1 -0
  34. package/dist/config/loader.d.ts +7 -0
  35. package/dist/config/loader.d.ts.map +1 -0
  36. package/dist/config/loader.js +85 -0
  37. package/dist/config/loader.js.map +1 -0
  38. package/dist/config/merger.d.ts +27 -0
  39. package/dist/config/merger.d.ts.map +1 -0
  40. package/dist/config/merger.js +41 -0
  41. package/dist/config/merger.js.map +1 -0
  42. package/dist/config/resolver.d.ts +28 -0
  43. package/dist/config/resolver.d.ts.map +1 -0
  44. package/dist/config/resolver.js +165 -0
  45. package/dist/config/resolver.js.map +1 -0
  46. package/dist/config/schema.d.ts +53 -0
  47. package/dist/config/schema.d.ts.map +1 -0
  48. package/dist/config/schema.js +42 -0
  49. package/dist/config/schema.js.map +1 -0
  50. package/dist/config/types.d.ts +17 -0
  51. package/dist/config/types.d.ts.map +1 -0
  52. package/dist/config/types.js +5 -0
  53. package/dist/config/types.js.map +1 -0
  54. package/dist/config/validator.d.ts +6 -0
  55. package/dist/config/validator.d.ts.map +1 -0
  56. package/dist/config/validator.js +17 -0
  57. package/dist/config/validator.js.map +1 -0
  58. package/dist/extractors/index.d.ts +9 -0
  59. package/dist/extractors/index.d.ts.map +1 -0
  60. package/dist/extractors/index.js +9 -0
  61. package/dist/extractors/index.js.map +1 -0
  62. package/dist/extractors/loader.d.ts +19 -0
  63. package/dist/extractors/loader.d.ts.map +1 -0
  64. package/dist/extractors/loader.js +120 -0
  65. package/dist/extractors/loader.js.map +1 -0
  66. package/dist/extractors/meta-yml-fn.d.ts +19 -0
  67. package/dist/extractors/meta-yml-fn.d.ts.map +1 -0
  68. package/dist/extractors/meta-yml-fn.js +66 -0
  69. package/dist/extractors/meta-yml-fn.js.map +1 -0
  70. package/dist/extractors/meta-yml.d.ts +24 -0
  71. package/dist/extractors/meta-yml.d.ts.map +1 -0
  72. package/dist/extractors/meta-yml.js +65 -0
  73. package/dist/extractors/meta-yml.js.map +1 -0
  74. package/dist/extractors/registry.d.ts +58 -0
  75. package/dist/extractors/registry.d.ts.map +1 -0
  76. package/dist/extractors/registry.js +114 -0
  77. package/dist/extractors/registry.js.map +1 -0
  78. package/dist/extractors/registry.spec.d.ts +2 -0
  79. package/dist/extractors/registry.spec.d.ts.map +1 -0
  80. package/dist/extractors/registry.spec.js +102 -0
  81. package/dist/extractors/registry.spec.js.map +1 -0
  82. package/dist/extractors/types.d.ts +34 -0
  83. package/dist/extractors/types.d.ts.map +1 -0
  84. package/dist/extractors/types.js +8 -0
  85. package/dist/extractors/types.js.map +1 -0
  86. package/dist/extractors/yaml-frontmatter-fn.d.ts +18 -0
  87. package/dist/extractors/yaml-frontmatter-fn.d.ts.map +1 -0
  88. package/dist/extractors/yaml-frontmatter-fn.js +73 -0
  89. package/dist/extractors/yaml-frontmatter-fn.js.map +1 -0
  90. package/dist/extractors/yaml-frontmatter.d.ts +22 -0
  91. package/dist/extractors/yaml-frontmatter.d.ts.map +1 -0
  92. package/dist/extractors/yaml-frontmatter.js +83 -0
  93. package/dist/extractors/yaml-frontmatter.js.map +1 -0
  94. package/dist/extractors/yaml-frontmatter.spec.d.ts +2 -0
  95. package/dist/extractors/yaml-frontmatter.spec.d.ts.map +1 -0
  96. package/dist/extractors/yaml-frontmatter.spec.js +134 -0
  97. package/dist/extractors/yaml-frontmatter.spec.js.map +1 -0
  98. package/dist/files/index.d.ts +5 -0
  99. package/dist/files/index.d.ts.map +1 -0
  100. package/dist/files/index.js +5 -0
  101. package/dist/files/index.js.map +1 -0
  102. package/dist/files/reader.d.ts +50 -0
  103. package/dist/files/reader.d.ts.map +1 -0
  104. package/dist/files/reader.js +62 -0
  105. package/dist/files/reader.js.map +1 -0
  106. package/dist/index.d.ts +29 -0
  107. package/dist/index.d.ts.map +1 -0
  108. package/dist/index.js +22 -0
  109. package/dist/index.js.map +1 -0
  110. package/dist/plugins/index.d.ts +4 -0
  111. package/dist/plugins/index.d.ts.map +1 -0
  112. package/dist/plugins/index.js +4 -0
  113. package/dist/plugins/index.js.map +1 -0
  114. package/dist/plugins/pipeline.d.ts +11 -0
  115. package/dist/plugins/pipeline.d.ts.map +1 -0
  116. package/dist/plugins/pipeline.js +24 -0
  117. package/dist/plugins/pipeline.js.map +1 -0
  118. package/dist/plugins/registry.d.ts +57 -0
  119. package/dist/plugins/registry.d.ts.map +1 -0
  120. package/dist/plugins/registry.js +93 -0
  121. package/dist/plugins/registry.js.map +1 -0
  122. package/dist/plugins/validation.d.ts +64 -0
  123. package/dist/plugins/validation.d.ts.map +1 -0
  124. package/dist/plugins/validation.js +55 -0
  125. package/dist/plugins/validation.js.map +1 -0
  126. package/dist/regions/index.d.ts +7 -0
  127. package/dist/regions/index.d.ts.map +1 -0
  128. package/dist/regions/index.js +6 -0
  129. package/dist/regions/index.js.map +1 -0
  130. package/dist/regions/languages.d.ts +15 -0
  131. package/dist/regions/languages.d.ts.map +1 -0
  132. package/dist/regions/languages.js +182 -0
  133. package/dist/regions/languages.js.map +1 -0
  134. package/dist/regions/parser.d.ts +63 -0
  135. package/dist/regions/parser.d.ts.map +1 -0
  136. package/dist/regions/parser.js +175 -0
  137. package/dist/regions/parser.js.map +1 -0
  138. package/dist/regions/parser.spec.d.ts +2 -0
  139. package/dist/regions/parser.spec.d.ts.map +1 -0
  140. package/dist/regions/parser.spec.js +190 -0
  141. package/dist/regions/parser.spec.js.map +1 -0
  142. package/dist/regions/types.d.ts +37 -0
  143. package/dist/regions/types.d.ts.map +1 -0
  144. package/dist/regions/types.js +5 -0
  145. package/dist/regions/types.js.map +1 -0
  146. package/dist/scanner/candidates.d.ts +24 -0
  147. package/dist/scanner/candidates.d.ts.map +1 -0
  148. package/dist/scanner/candidates.js +83 -0
  149. package/dist/scanner/candidates.js.map +1 -0
  150. package/dist/scanner/index.d.ts +8 -0
  151. package/dist/scanner/index.d.ts.map +1 -0
  152. package/dist/scanner/index.js +6 -0
  153. package/dist/scanner/index.js.map +1 -0
  154. package/dist/scanner/scan.d.ts +40 -0
  155. package/dist/scanner/scan.d.ts.map +1 -0
  156. package/dist/scanner/scan.js +44 -0
  157. package/dist/scanner/scan.js.map +1 -0
  158. package/dist/scanner/scanner.d.ts +29 -0
  159. package/dist/scanner/scanner.d.ts.map +1 -0
  160. package/dist/scanner/scanner.js +296 -0
  161. package/dist/scanner/scanner.js.map +1 -0
  162. package/dist/scanner/scanner.spec.d.ts +2 -0
  163. package/dist/scanner/scanner.spec.d.ts.map +1 -0
  164. package/dist/scanner/scanner.spec.js +262 -0
  165. package/dist/scanner/scanner.spec.js.map +1 -0
  166. package/dist/scanner/types.d.ts +43 -0
  167. package/dist/scanner/types.d.ts.map +1 -0
  168. package/dist/scanner/types.js +5 -0
  169. package/dist/scanner/types.js.map +1 -0
  170. package/dist/schema/index.d.ts +4 -0
  171. package/dist/schema/index.d.ts.map +1 -0
  172. package/dist/schema/index.js +4 -0
  173. package/dist/schema/index.js.map +1 -0
  174. package/dist/schema/merger.d.ts +35 -0
  175. package/dist/schema/merger.d.ts.map +1 -0
  176. package/dist/schema/merger.js +161 -0
  177. package/dist/schema/merger.js.map +1 -0
  178. package/dist/schema/typegen.d.ts +13 -0
  179. package/dist/schema/typegen.d.ts.map +1 -0
  180. package/dist/schema/typegen.js +125 -0
  181. package/dist/schema/typegen.js.map +1 -0
  182. package/dist/schema/validator.d.ts +7 -0
  183. package/dist/schema/validator.d.ts.map +1 -0
  184. package/dist/schema/validator.js +32 -0
  185. package/dist/schema/validator.js.map +1 -0
  186. package/dist/types/default-map.d.ts +21 -0
  187. package/dist/types/default-map.d.ts.map +1 -0
  188. package/dist/types/default-map.js +32 -0
  189. package/dist/types/default-map.js.map +1 -0
  190. package/dist/types/extended-iterable.d.ts +197 -0
  191. package/dist/types/extended-iterable.d.ts.map +1 -0
  192. package/dist/types/extended-iterable.js +769 -0
  193. package/dist/types/extended-iterable.js.map +1 -0
  194. package/dist/types/guards.d.ts +2 -0
  195. package/dist/types/guards.d.ts.map +1 -0
  196. package/dist/types/guards.js +2 -0
  197. package/dist/types/guards.js.map +1 -0
  198. package/dist/types/index.d.ts +11 -0
  199. package/dist/types/index.d.ts.map +1 -0
  200. package/dist/types/index.js +10 -0
  201. package/dist/types/index.js.map +1 -0
  202. package/package.json +61 -0
@@ -0,0 +1,769 @@
1
+ // Shared done sentinel to reduce allocations
2
+ const DONE = { done: true, value: undefined };
3
+ // --- Sync iterator classes ---
4
+ // Classes give V8 stable hidden classes and monomorphic inline caches on next(),
5
+ // which outperforms plain object factories on chained operations.
6
+ class MapIterator {
7
+ source;
8
+ fn;
9
+ r = { done: false, value: undefined };
10
+ constructor(source, fn) {
11
+ this.source = source;
12
+ this.fn = fn;
13
+ }
14
+ next() {
15
+ const result = this.source.next();
16
+ if (result.done)
17
+ return DONE;
18
+ this.r.value = this.fn(result.value);
19
+ return this.r;
20
+ }
21
+ [Symbol.iterator]() {
22
+ return this;
23
+ }
24
+ }
25
+ class FilterIterator {
26
+ source;
27
+ fn;
28
+ r = { done: false, value: undefined };
29
+ constructor(source, fn) {
30
+ this.source = source;
31
+ this.fn = fn;
32
+ }
33
+ next() {
34
+ while (true) {
35
+ const result = this.source.next();
36
+ if (result.done)
37
+ return DONE;
38
+ if (this.fn(result.value)) {
39
+ this.r.value = result.value;
40
+ return this.r;
41
+ }
42
+ }
43
+ }
44
+ [Symbol.iterator]() {
45
+ return this;
46
+ }
47
+ }
48
+ class TakeIterator {
49
+ source;
50
+ n;
51
+ r = { done: false, value: undefined };
52
+ count = 0;
53
+ constructor(source, n) {
54
+ this.source = source;
55
+ this.n = n;
56
+ }
57
+ next() {
58
+ if (this.count >= this.n)
59
+ return DONE;
60
+ const result = this.source.next();
61
+ if (result.done)
62
+ return DONE;
63
+ this.count++;
64
+ this.r.value = result.value;
65
+ return this.r;
66
+ }
67
+ [Symbol.iterator]() {
68
+ return this;
69
+ }
70
+ }
71
+ class FlatIterator {
72
+ source;
73
+ r = { done: false, value: undefined };
74
+ inner = null;
75
+ constructor(source) {
76
+ this.source = source;
77
+ }
78
+ next() {
79
+ while (true) {
80
+ if (this.inner) {
81
+ const result = this.inner.next();
82
+ if (!result.done) {
83
+ this.r.value = result.value;
84
+ return this.r;
85
+ }
86
+ this.inner = null;
87
+ }
88
+ const result = this.source.next();
89
+ if (result.done)
90
+ return DONE;
91
+ const value = result.value;
92
+ if (value != null &&
93
+ typeof value !== 'string' &&
94
+ typeof value[Symbol.iterator] === 'function') {
95
+ this.inner = value[Symbol.iterator]();
96
+ }
97
+ else {
98
+ this.r.value = value;
99
+ return this.r;
100
+ }
101
+ }
102
+ }
103
+ [Symbol.iterator]() {
104
+ return this;
105
+ }
106
+ }
107
+ class PrefixIterator {
108
+ source;
109
+ prefixIt;
110
+ constructor(prefix, source) {
111
+ this.source = source;
112
+ this.prefixIt = prefix[Symbol.iterator]();
113
+ }
114
+ next() {
115
+ if (this.prefixIt) {
116
+ const result = this.prefixIt.next();
117
+ if (!result.done)
118
+ return result;
119
+ this.prefixIt = null;
120
+ }
121
+ return this.source.next();
122
+ }
123
+ [Symbol.iterator]() {
124
+ return this;
125
+ }
126
+ }
127
+ // --- Async iterator classes ---
128
+ class AsyncMapIterator {
129
+ source;
130
+ fn;
131
+ constructor(source, fn) {
132
+ this.source = source;
133
+ this.fn = fn;
134
+ }
135
+ async next() {
136
+ const result = await this.source.next();
137
+ if (result.done)
138
+ return DONE;
139
+ return { done: false, value: await this.fn(result.value) };
140
+ }
141
+ [Symbol.asyncIterator]() {
142
+ return this;
143
+ }
144
+ }
145
+ class AsyncFilterIterator {
146
+ source;
147
+ fn;
148
+ constructor(source, fn) {
149
+ this.source = source;
150
+ this.fn = fn;
151
+ }
152
+ async next() {
153
+ while (true) {
154
+ const result = await this.source.next();
155
+ if (result.done)
156
+ return DONE;
157
+ if (await this.fn(result.value))
158
+ return { done: false, value: result.value };
159
+ }
160
+ }
161
+ [Symbol.asyncIterator]() {
162
+ return this;
163
+ }
164
+ }
165
+ class AsyncTakeIterator {
166
+ source;
167
+ n;
168
+ count = 0;
169
+ constructor(source, n) {
170
+ this.source = source;
171
+ this.n = n;
172
+ }
173
+ async next() {
174
+ if (this.count >= this.n)
175
+ return DONE;
176
+ const result = await this.source.next();
177
+ if (result.done)
178
+ return DONE;
179
+ this.count++;
180
+ return result;
181
+ }
182
+ [Symbol.asyncIterator]() {
183
+ return this;
184
+ }
185
+ }
186
+ function createSpliceGenerators(source, matcher, deleteCount, insertIterable) {
187
+ const state = {
188
+ phase: 'seeking',
189
+ deletedCache: [],
190
+ slicedCache: [],
191
+ deletedPtr: 0,
192
+ slicedPtr: 0,
193
+ deleteRemaining: deleteCount,
194
+ insertIterator: null,
195
+ sourceIterator: source[Symbol.iterator](),
196
+ };
197
+ function* slicedGenerator() {
198
+ while (true) {
199
+ while (state.slicedPtr < state.slicedCache.length) {
200
+ yield state.slicedCache[state.slicedPtr++];
201
+ }
202
+ if (state.phase === 'seeking') {
203
+ const next = state.sourceIterator.next();
204
+ if (next.done) {
205
+ state.phase = 'done';
206
+ return;
207
+ }
208
+ const val = next.value;
209
+ if (matcher(val)) {
210
+ state.phase = 'deleting';
211
+ state.deletedCache.push(val);
212
+ state.deleteRemaining--;
213
+ }
214
+ else {
215
+ state.slicedCache.push(val);
216
+ state.slicedPtr++;
217
+ yield val;
218
+ }
219
+ }
220
+ else if (state.phase === 'deleting') {
221
+ if (state.deleteRemaining > 0) {
222
+ const next = state.sourceIterator.next();
223
+ if (next.done) {
224
+ state.phase = 'done';
225
+ return;
226
+ }
227
+ state.deletedCache.push(next.value);
228
+ state.deleteRemaining--;
229
+ }
230
+ else {
231
+ state.phase = 'inserting';
232
+ state.insertIterator = insertIterable[Symbol.iterator]();
233
+ }
234
+ }
235
+ else if (state.phase === 'inserting') {
236
+ if (state.insertIterator === null) {
237
+ state.insertIterator = insertIterable[Symbol.iterator]();
238
+ }
239
+ const next = state.insertIterator.next();
240
+ if (next.done) {
241
+ state.phase = 'done';
242
+ }
243
+ else {
244
+ state.slicedCache.push(next.value);
245
+ state.slicedPtr++;
246
+ yield next.value;
247
+ }
248
+ }
249
+ else if (state.phase === 'done') {
250
+ const next = state.sourceIterator.next();
251
+ if (next.done)
252
+ return;
253
+ state.slicedCache.push(next.value);
254
+ state.slicedPtr++;
255
+ yield next.value;
256
+ }
257
+ }
258
+ }
259
+ function* deletedGenerator() {
260
+ while (true) {
261
+ while (state.deletedPtr < state.deletedCache.length) {
262
+ yield state.deletedCache[state.deletedPtr++];
263
+ }
264
+ if (state.phase === 'seeking' || state.phase === 'deleting') {
265
+ const slicedIter = slicedGenerator();
266
+ let result = slicedIter.next();
267
+ // slicedGenerator mutates state.phase as it iterates, so re-read
268
+ // through the full type to avoid TS narrowing from the outer `if`.
269
+ while (!result.done && state.phase !== 'done') {
270
+ result = slicedIter.next();
271
+ }
272
+ }
273
+ if (state.deletedPtr >= state.deletedCache.length) {
274
+ if (state.phase === 'done' || state.phase === 'inserting')
275
+ return;
276
+ }
277
+ }
278
+ }
279
+ return {
280
+ sliced: slicedGenerator(),
281
+ deleted: deletedGenerator(),
282
+ };
283
+ }
284
+ async function createAsyncSpliceGenerators(source, matcher, deleteCount, insertIterable) {
285
+ const state = {
286
+ phase: 'seeking',
287
+ deletedCache: [],
288
+ slicedCache: [],
289
+ deletedPtr: 0,
290
+ slicedPtr: 0,
291
+ deleteRemaining: deleteCount,
292
+ insertIterator: null,
293
+ sourceIterator: source[Symbol.asyncIterator](),
294
+ };
295
+ async function* slicedGenerator() {
296
+ while (true) {
297
+ while (state.slicedPtr < state.slicedCache.length) {
298
+ yield state.slicedCache[state.slicedPtr++];
299
+ }
300
+ if (state.phase === 'seeking') {
301
+ const next = await state.sourceIterator.next();
302
+ if (next.done) {
303
+ state.phase = 'done';
304
+ return;
305
+ }
306
+ const val = next.value;
307
+ if (await matcher(val)) {
308
+ state.phase = 'deleting';
309
+ state.deletedCache.push(val);
310
+ state.deleteRemaining--;
311
+ }
312
+ else {
313
+ state.slicedCache.push(val);
314
+ state.slicedPtr++;
315
+ yield val;
316
+ }
317
+ }
318
+ else if (state.phase === 'deleting') {
319
+ if (state.deleteRemaining > 0) {
320
+ const next = await state.sourceIterator.next();
321
+ if (next.done) {
322
+ state.phase = 'done';
323
+ return;
324
+ }
325
+ state.deletedCache.push(next.value);
326
+ state.deleteRemaining--;
327
+ }
328
+ else {
329
+ state.phase = 'inserting';
330
+ state.insertIterator = insertIterable[Symbol.asyncIterator]();
331
+ }
332
+ }
333
+ else if (state.phase === 'inserting') {
334
+ if (state.insertIterator === null) {
335
+ state.insertIterator = insertIterable[Symbol.asyncIterator]();
336
+ }
337
+ const next = await state.insertIterator.next();
338
+ if (next.done) {
339
+ state.phase = 'done';
340
+ }
341
+ else {
342
+ state.slicedCache.push(next.value);
343
+ state.slicedPtr++;
344
+ yield next.value;
345
+ }
346
+ }
347
+ else if (state.phase === 'done') {
348
+ const next = await state.sourceIterator.next();
349
+ if (next.done)
350
+ return;
351
+ state.slicedCache.push(next.value);
352
+ state.slicedPtr++;
353
+ yield next.value;
354
+ }
355
+ }
356
+ }
357
+ async function* deletedGenerator() {
358
+ while (true) {
359
+ while (state.deletedPtr < state.deletedCache.length) {
360
+ yield state.deletedCache[state.deletedPtr++];
361
+ }
362
+ if (state.phase === 'seeking' || state.phase === 'deleting') {
363
+ const slicedIter = slicedGenerator();
364
+ let result = await slicedIter.next();
365
+ // slicedGenerator mutates state.phase as it iterates, so re-read
366
+ // through the full type to avoid TS narrowing from the outer `if`.
367
+ while (!result.done &&
368
+ state.phase !== 'done') {
369
+ result = await slicedIter.next();
370
+ }
371
+ }
372
+ if (state.deletedPtr >= state.deletedCache.length) {
373
+ if (state.phase === 'done' || state.phase === 'inserting')
374
+ return;
375
+ }
376
+ }
377
+ }
378
+ return {
379
+ sliced: slicedGenerator(),
380
+ deleted: deletedGenerator(),
381
+ };
382
+ }
383
+ function asyncIterableFrom(factory) {
384
+ return { [Symbol.asyncIterator]: factory };
385
+ }
386
+ /**
387
+ * A wrapper around Iterable that provides chainable transformation methods.
388
+ * Each method returns a new ExtendedIterable wrapping the source,
389
+ * mirroring how Array methods work but with lazy evaluation.
390
+ *
391
+ * @example
392
+ * ```typescript
393
+ * const numbers = new ExtendedIterable([1, 2, 3]);
394
+ * const doubled = numbers.map(x => x * 2).collect(); // [2, 4, 6]
395
+ *
396
+ * // Works with any iterable, including generators
397
+ * const result = new ExtendedIterable(myGenerator())
398
+ * .map(transform)
399
+ * .join(', ');
400
+ * ```
401
+ */
402
+ export class ExtendedIterable {
403
+ _iterFn;
404
+ constructor(iterable) {
405
+ // Store a factory so we can create fresh iterators on each iteration.
406
+ // For iterables that are already single-use (generators), this preserves
407
+ // the existing behavior — iterating twice just yields nothing the second time.
408
+ this._iterFn = () => iterable[Symbol.iterator]();
409
+ }
410
+ // Internal: create from a factory directly, skipping the iterable wrapper
411
+ static _from(factory) {
412
+ const inst = Object.create(ExtendedIterable.prototype);
413
+ inst._iterFn = factory;
414
+ return inst;
415
+ }
416
+ /**
417
+ * Flattens one level of nesting by yielding elements from nested iterables.
418
+ * Non-iterable values are yielded as-is. Strings are not split into characters.
419
+ */
420
+ flat() {
421
+ const parentIter = this._iterFn;
422
+ return ExtendedIterable._from(() => new FlatIterator(parentIter()));
423
+ }
424
+ /**
425
+ * Maps each element through a transformation function.
426
+ * Evaluation is lazy - the function is called only when iterating.
427
+ */
428
+ map(fn) {
429
+ const parentIter = this._iterFn;
430
+ return ExtendedIterable._from(() => new MapIterator(parentIter(), fn));
431
+ }
432
+ /**
433
+ * Filters elements using a predicate function.
434
+ * Supports type guards for narrowing.
435
+ */
436
+ filter(predicate) {
437
+ const parentIter = this._iterFn;
438
+ return ExtendedIterable._from(() => new FilterIterator(parentIter(), predicate));
439
+ }
440
+ /**
441
+ * Takes the first n elements.
442
+ */
443
+ take(n) {
444
+ const parentIter = this._iterFn;
445
+ return ExtendedIterable._from(() => new TakeIterator(parentIter(), n));
446
+ }
447
+ some(predicate) {
448
+ const iterator = this[Symbol.iterator]();
449
+ const processAsync = async (pending) => {
450
+ if (await pending)
451
+ return true;
452
+ for (let next = iterator.next(); !next.done; next = iterator.next()) {
453
+ if (await predicate(next.value))
454
+ return true;
455
+ }
456
+ return false;
457
+ };
458
+ for (let next = iterator.next(); !next.done; next = iterator.next()) {
459
+ const result = predicate(next.value);
460
+ if (result instanceof Promise) {
461
+ return processAsync(result);
462
+ }
463
+ if (result)
464
+ return true;
465
+ }
466
+ return false;
467
+ }
468
+ find(predicate) {
469
+ const iterator = this[Symbol.iterator]();
470
+ const processAsync = async (currentVal, pending) => {
471
+ if (await pending)
472
+ return currentVal;
473
+ for (let next = iterator.next(); !next.done; next = iterator.next()) {
474
+ if (await predicate(next.value))
475
+ return next.value;
476
+ }
477
+ return undefined;
478
+ };
479
+ for (let next = iterator.next(); !next.done; next = iterator.next()) {
480
+ const result = predicate(next.value);
481
+ if (result instanceof Promise) {
482
+ return processAsync(next.value, result);
483
+ }
484
+ if (result)
485
+ return next.value;
486
+ }
487
+ return undefined;
488
+ }
489
+ reduce(fn, ...rest) {
490
+ const it = this[Symbol.iterator]();
491
+ let acc;
492
+ if (rest.length > 0) {
493
+ acc = rest[0];
494
+ }
495
+ else {
496
+ const first = it.next();
497
+ if (first.done) {
498
+ throw new TypeError('Reduce of empty iterable with no initial value');
499
+ }
500
+ acc = first.value;
501
+ }
502
+ for (let r = it.next(); !r.done; r = it.next()) {
503
+ acc = fn(acc, r.value);
504
+ }
505
+ return acc;
506
+ }
507
+ /**
508
+ * Collects all elements into an array.
509
+ */
510
+ collect() {
511
+ const arr = [];
512
+ const it = this[Symbol.iterator]();
513
+ for (let r = it.next(); !r.done; r = it.next()) {
514
+ arr.push(r.value);
515
+ }
516
+ return arr;
517
+ }
518
+ /**
519
+ * Joins all elements into a string with a separator.
520
+ * Elements are converted to strings using toString().
521
+ */
522
+ join(separator) {
523
+ const it = this[Symbol.iterator]();
524
+ let r = it.next();
525
+ if (r.done)
526
+ return '';
527
+ let str = String(r.value);
528
+ for (r = it.next(); !r.done; r = it.next()) {
529
+ str += separator + String(r.value);
530
+ }
531
+ return str;
532
+ }
533
+ /**
534
+ * Prepends an iterable to the start of this iterable.
535
+ */
536
+ prefix(prefix) {
537
+ const parentIter = this._iterFn;
538
+ return ExtendedIterable._from(() => new PrefixIterator(prefix, parentIter()));
539
+ }
540
+ /**
541
+ * Removes elements from the iterable and optionally inserts new elements.
542
+ * Returns both the modified iterable and the deleted elements.
543
+ * Both iterables share state - iterating either will cache results for the other.
544
+ *
545
+ * @param matcher - Predicate to find the splice position
546
+ * @param deleteCount - Number of elements to remove after the match
547
+ * @param insertIterable - Elements to insert after removing
548
+ * @returns Object with `sliced` (modified iterable) and `deleted` (removed elements)
549
+ *
550
+ * @example
551
+ * ```typescript
552
+ * const { deleted, sliced } = iter([1, 2, 3, 4, 5])
553
+ * .splice((el) => el === 3, 2, iter([10, 20]));
554
+ * sliced.collect(); // [1, 2, 10, 20, 5]
555
+ * deleted.collect(); // [3, 4]
556
+ * ```
557
+ */
558
+ splice(matcher, deleteCount, insertIterable) {
559
+ const { sliced, deleted } = createSpliceGenerators(this, matcher, deleteCount, insertIterable);
560
+ return {
561
+ sliced: new ExtendedIterable(sliced),
562
+ deleted: new ExtendedIterable(deleted),
563
+ };
564
+ }
565
+ [Symbol.iterator]() {
566
+ return this._iterFn();
567
+ }
568
+ }
569
+ export class AsyncExtendedIterable {
570
+ asyncIterable;
571
+ constructor(iterable) {
572
+ if (Symbol.asyncIterator in iterable) {
573
+ this.asyncIterable = iterable;
574
+ }
575
+ else {
576
+ const syncIterable = iterable;
577
+ this.asyncIterable = {
578
+ async *[Symbol.asyncIterator]() {
579
+ for (const val of syncIterable) {
580
+ yield val;
581
+ }
582
+ },
583
+ };
584
+ }
585
+ }
586
+ /**
587
+ * Maps each element through a transformation function.
588
+ * The function can be sync or async.
589
+ * Evaluation is lazy - the function is called only when iterating.
590
+ */
591
+ map(fn) {
592
+ const source = this.asyncIterable;
593
+ return new AsyncExtendedIterable(asyncIterableFrom(() => new AsyncMapIterator(source[Symbol.asyncIterator](), fn)));
594
+ }
595
+ /**
596
+ * Filters elements using a predicate function.
597
+ * The predicate can be sync or async.
598
+ */
599
+ filter(predicate) {
600
+ const source = this.asyncIterable;
601
+ return new AsyncExtendedIterable(asyncIterableFrom(() => new AsyncFilterIterator(source[Symbol.asyncIterator](), predicate)));
602
+ }
603
+ async reduce(fn, ...rest) {
604
+ const it = this[Symbol.asyncIterator]();
605
+ let acc;
606
+ if (rest.length > 0) {
607
+ acc = rest[0];
608
+ }
609
+ else {
610
+ const first = await it.next();
611
+ if (first.done) {
612
+ throw new TypeError('Reduce of empty iterable with no initial value');
613
+ }
614
+ acc = first.value;
615
+ }
616
+ for (let r = await it.next(); !r.done; r = await it.next()) {
617
+ acc = await fn(acc, r.value);
618
+ }
619
+ return acc;
620
+ }
621
+ /**
622
+ * Collects all elements into an array.
623
+ */
624
+ async collect() {
625
+ const arr = [];
626
+ for await (const val of this) {
627
+ arr.push(val);
628
+ }
629
+ return arr;
630
+ }
631
+ /**
632
+ * Joins all elements into a string with a separator.
633
+ * Elements are converted to strings using String().
634
+ */
635
+ async join(separator) {
636
+ const arr = await this.collect();
637
+ return arr.map(String).join(separator);
638
+ }
639
+ /**
640
+ * Takes the first n elements.
641
+ */
642
+ take(n) {
643
+ const source = this.asyncIterable;
644
+ return new AsyncExtendedIterable(asyncIterableFrom(() => new AsyncTakeIterator(source[Symbol.asyncIterator](), n)));
645
+ }
646
+ /**
647
+ * Tests whether at least one element passes the predicate.
648
+ * Short-circuits on first match. Predicate can be sync or async.
649
+ */
650
+ async some(predicate) {
651
+ for await (const val of this) {
652
+ if (await predicate(val)) {
653
+ return true;
654
+ }
655
+ }
656
+ return false;
657
+ }
658
+ /**
659
+ * Returns the first element that passes the predicate, or undefined.
660
+ * Short-circuits on first match. Predicate can be sync or async.
661
+ */
662
+ async find(predicate) {
663
+ for await (const val of this) {
664
+ if (await predicate(val)) {
665
+ return val;
666
+ }
667
+ }
668
+ return undefined;
669
+ }
670
+ /**
671
+ * Removes elements from the async iterable and optionally inserts new elements.
672
+ * Returns both the modified iterable and the deleted elements.
673
+ * Both iterables share state - iterating either will cache results for the other.
674
+ */
675
+ async splice(matcher, deleteCount, insertIterable) {
676
+ const asyncInsert = Symbol.asyncIterator in insertIterable
677
+ ? insertIterable
678
+ : {
679
+ async *[Symbol.asyncIterator]() {
680
+ for (const val of insertIterable) {
681
+ yield val;
682
+ }
683
+ },
684
+ };
685
+ const { sliced, deleted } = await createAsyncSpliceGenerators(this, matcher, deleteCount, asyncInsert);
686
+ return {
687
+ sliced: new AsyncExtendedIterable(sliced),
688
+ deleted: new AsyncExtendedIterable(deleted),
689
+ };
690
+ }
691
+ [Symbol.asyncIterator]() {
692
+ return this.asyncIterable[Symbol.asyncIterator]();
693
+ }
694
+ }
695
+ /**
696
+ * Helper to create an AsyncExtendedIterable from any iterable.
697
+ */
698
+ export function asyncIter(iterable) {
699
+ return new AsyncExtendedIterable(iterable);
700
+ }
701
+ /**
702
+ * Returns an AsyncExtendedIterable that yields promise results as they settle,
703
+ * in completion order (not input order).
704
+ *
705
+ * Like Promise.allSettled, but streaming - you get results as soon as they're ready,
706
+ * with full chaining support.
707
+ *
708
+ * @example
709
+ * ```typescript
710
+ * const promises = [
711
+ * fetch('/slow'), // takes 3s
712
+ * fetch('/fast'), // takes 1s
713
+ * fetch('/medium'), // takes 2s
714
+ * ];
715
+ *
716
+ * // Results arrive in order: fast, medium, slow
717
+ * for await (const result of asSettled(promises)) {
718
+ * if (result.status === 'fulfilled') {
719
+ * console.log('Got:', result.value);
720
+ * } else {
721
+ * console.log('Failed:', result.reason);
722
+ * }
723
+ * }
724
+ *
725
+ * // Chain operations
726
+ * const firstThreeSuccesses = await asSettled(promises)
727
+ * .filter(r => r.status === 'fulfilled')
728
+ * .map(r => (r as PromiseFulfilledResult<Response>).value)
729
+ * .take(3)
730
+ * .collect();
731
+ * ```
732
+ */
733
+ export function asSettled(promises) {
734
+ return new AsyncExtendedIterable(asSettledGen(promises));
735
+ }
736
+ async function* asSettledGen(promises) {
737
+ const queue = [];
738
+ let notifyReady = null;
739
+ let remaining = 0;
740
+ for (const p of promises) {
741
+ remaining++;
742
+ Promise.resolve(p).then((value) => {
743
+ queue.push({ status: 'fulfilled', value });
744
+ notifyReady?.();
745
+ }, (reason) => {
746
+ queue.push({ status: 'rejected', reason });
747
+ notifyReady?.();
748
+ });
749
+ }
750
+ while (remaining > 0) {
751
+ if (queue.length === 0) {
752
+ await new Promise((resolve) => {
753
+ notifyReady = resolve;
754
+ });
755
+ notifyReady = null;
756
+ }
757
+ while (queue.length > 0 && remaining > 0) {
758
+ yield queue.shift();
759
+ remaining--;
760
+ }
761
+ }
762
+ }
763
+ /**
764
+ * Helper to create an ExtendedIterable from any iterable.
765
+ */
766
+ export function iter(iterable) {
767
+ return new ExtendedIterable(iterable);
768
+ }
769
+ //# sourceMappingURL=extended-iterable.js.map