@shutterstock/p-map-iterable 0.0.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 (55) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +110 -0
  3. package/dist/blocking-queue.d.ts +57 -0
  4. package/dist/blocking-queue.d.ts.map +1 -0
  5. package/dist/blocking-queue.js +193 -0
  6. package/dist/blocking-queue.js.map +1 -0
  7. package/dist/blocking-queue.test.d.ts +2 -0
  8. package/dist/blocking-queue.test.d.ts.map +1 -0
  9. package/dist/blocking-queue.test.js +175 -0
  10. package/dist/blocking-queue.test.js.map +1 -0
  11. package/dist/index.d.ts +8 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +16 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/iterable-mapper.d.ts +104 -0
  16. package/dist/iterable-mapper.d.ts.map +1 -0
  17. package/dist/iterable-mapper.js +321 -0
  18. package/dist/iterable-mapper.js.map +1 -0
  19. package/dist/iterable-mapper.test.d.ts +2 -0
  20. package/dist/iterable-mapper.test.d.ts.map +1 -0
  21. package/dist/iterable-mapper.test.js +1421 -0
  22. package/dist/iterable-mapper.test.js.map +1 -0
  23. package/dist/iterable-queue-mapper-simple.d.ts +49 -0
  24. package/dist/iterable-queue-mapper-simple.d.ts.map +1 -0
  25. package/dist/iterable-queue-mapper-simple.js +92 -0
  26. package/dist/iterable-queue-mapper-simple.js.map +1 -0
  27. package/dist/iterable-queue-mapper-simple.test.d.ts +2 -0
  28. package/dist/iterable-queue-mapper-simple.test.d.ts.map +1 -0
  29. package/dist/iterable-queue-mapper-simple.test.js +103 -0
  30. package/dist/iterable-queue-mapper-simple.test.js.map +1 -0
  31. package/dist/iterable-queue-mapper.d.ts +73 -0
  32. package/dist/iterable-queue-mapper.d.ts.map +1 -0
  33. package/dist/iterable-queue-mapper.js +72 -0
  34. package/dist/iterable-queue-mapper.js.map +1 -0
  35. package/dist/iterable-queue-mapper.test.d.ts +2 -0
  36. package/dist/iterable-queue-mapper.test.d.ts.map +1 -0
  37. package/dist/iterable-queue-mapper.test.js +174 -0
  38. package/dist/iterable-queue-mapper.test.js.map +1 -0
  39. package/dist/iterable-queue.d.ts +26 -0
  40. package/dist/iterable-queue.d.ts.map +1 -0
  41. package/dist/iterable-queue.js +34 -0
  42. package/dist/iterable-queue.js.map +1 -0
  43. package/dist/iterable-queue.test.d.ts +2 -0
  44. package/dist/iterable-queue.test.d.ts.map +1 -0
  45. package/dist/iterable-queue.test.js +252 -0
  46. package/dist/iterable-queue.test.js.map +1 -0
  47. package/dist/queue.d.ts +9 -0
  48. package/dist/queue.d.ts.map +1 -0
  49. package/dist/queue.js +33 -0
  50. package/dist/queue.js.map +1 -0
  51. package/dist/queue.test.d.ts +2 -0
  52. package/dist/queue.test.d.ts.map +1 -0
  53. package/dist/queue.test.js +75 -0
  54. package/dist/queue.test.js.map +1 -0
  55. package/package.json +45 -0
@@ -0,0 +1,1421 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ /* eslint-disable @typescript-eslint/no-explicit-any */
5
+ /// <reference types="jest" />
6
+ const iterable_mapper_1 = require("./iterable-mapper");
7
+ const util_1 = require("util");
8
+ const sleep = (0, util_1.promisify)(setTimeout);
9
+ function mapper({ value, ms }) {
10
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
11
+ yield sleep(ms);
12
+ return value;
13
+ });
14
+ }
15
+ class SleepIterator {
16
+ constructor(max) {
17
+ this._current = 1;
18
+ this._max = max;
19
+ }
20
+ [Symbol.asyncIterator]() {
21
+ return tslib_1.__asyncGenerator(this, arguments, function* _a() {
22
+ for (let i = 0; i < this._max; i++) {
23
+ yield tslib_1.__await(sleep(1 * (i % 10)));
24
+ if (this._current <= this._max) {
25
+ yield yield tslib_1.__await(this._current);
26
+ }
27
+ this._current++;
28
+ }
29
+ });
30
+ }
31
+ }
32
+ class ThrowingIterator {
33
+ constructor(max, throwOnIndex, delayMS) {
34
+ this._max = max;
35
+ this._throwOnIndex = throwOnIndex;
36
+ this._delayMS = delayMS;
37
+ }
38
+ [Symbol.asyncIterator]() {
39
+ let index = 0;
40
+ const max = this._max;
41
+ const delayMS = this._delayMS;
42
+ const throwOnIndex = this._throwOnIndex;
43
+ return {
44
+ next() {
45
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
46
+ yield sleep(delayMS);
47
+ if (index === throwOnIndex) {
48
+ throw new Error(`throwing on index ${index}`);
49
+ }
50
+ const item = { value: index, done: index === max };
51
+ index++;
52
+ return item;
53
+ });
54
+ },
55
+ };
56
+ }
57
+ }
58
+ describe('IterableMapper', () => {
59
+ const sourceNextSpy = jest.spyOn(iterable_mapper_1.IterableMapper.prototype, 'sourceNext');
60
+ const startAnotherRunnerSpy = jest.spyOn(iterable_mapper_1.IterableMapper.prototype, 'startAnotherRunner');
61
+ beforeAll(() => {
62
+ // nothing
63
+ });
64
+ beforeEach(() => {
65
+ jest.clearAllMocks();
66
+ });
67
+ describe('simple tests', () => {
68
+ it('simple mapper works - sync mapper', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
69
+ var _a, e_1, _b, _c;
70
+ const max = 100;
71
+ const iterator = new SleepIterator(max);
72
+ let total = 0;
73
+ let callCount = 0;
74
+ const prefetcher = new iterable_mapper_1.IterableMapper(iterator, (value) => {
75
+ callCount++;
76
+ total += value;
77
+ return total;
78
+ });
79
+ let lastTotal = 0;
80
+ let loopCount = 0;
81
+ try {
82
+ for (var _d = true, prefetcher_1 = tslib_1.__asyncValues(prefetcher), prefetcher_1_1; prefetcher_1_1 = yield prefetcher_1.next(), _a = prefetcher_1_1.done, !_a;) {
83
+ _c = prefetcher_1_1.value;
84
+ _d = false;
85
+ try {
86
+ const item = _c;
87
+ loopCount++;
88
+ if (item > lastTotal) {
89
+ lastTotal = item;
90
+ }
91
+ }
92
+ finally {
93
+ _d = true;
94
+ }
95
+ }
96
+ }
97
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
98
+ finally {
99
+ try {
100
+ if (!_d && !_a && (_b = prefetcher_1.return)) yield _b.call(prefetcher_1);
101
+ }
102
+ finally { if (e_1) throw e_1.error; }
103
+ }
104
+ expect(callCount).toBe(max);
105
+ expect(loopCount).toBe(max);
106
+ expect(total).toBe((max * (max + 1)) / 2);
107
+ expect(lastTotal).toBe((max * (max + 1)) / 2);
108
+ }));
109
+ it('simple mapper works - async mapper', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
110
+ var _e, e_2, _f, _g;
111
+ const max = 100;
112
+ const iterator = new SleepIterator(max);
113
+ let total = 0;
114
+ let callCount = 0;
115
+ const prefetcher = new iterable_mapper_1.IterableMapper(iterator, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
116
+ callCount++;
117
+ total += value;
118
+ yield sleep(10 * (callCount % 6));
119
+ return total;
120
+ }));
121
+ let lastTotal = 0;
122
+ let loopCount = 0;
123
+ try {
124
+ for (var _h = true, prefetcher_2 = tslib_1.__asyncValues(prefetcher), prefetcher_2_1; prefetcher_2_1 = yield prefetcher_2.next(), _e = prefetcher_2_1.done, !_e;) {
125
+ _g = prefetcher_2_1.value;
126
+ _h = false;
127
+ try {
128
+ const item = _g;
129
+ loopCount++;
130
+ if (item > lastTotal) {
131
+ lastTotal = item;
132
+ }
133
+ }
134
+ finally {
135
+ _h = true;
136
+ }
137
+ }
138
+ }
139
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
140
+ finally {
141
+ try {
142
+ if (!_h && !_e && (_f = prefetcher_2.return)) yield _f.call(prefetcher_2);
143
+ }
144
+ finally { if (e_2) throw e_2.error; }
145
+ }
146
+ expect(callCount).toBe(max);
147
+ expect(loopCount).toBe(max);
148
+ expect(total).toBe((max * (max + 1)) / 2);
149
+ expect(lastTotal).toBe((max * (max + 1)) / 2);
150
+ }));
151
+ it('async mapper works - parallel next() calls', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
152
+ var _j, e_3, _k, _l;
153
+ const max = 100;
154
+ const inputIterator = new SleepIterator(max);
155
+ let total = 0;
156
+ let callCount = 0;
157
+ const prefetcher = new iterable_mapper_1.IterableMapper(inputIterator, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
158
+ callCount++;
159
+ total += value;
160
+ yield sleep(10 * (callCount % 6));
161
+ return total;
162
+ }));
163
+ let lastTotal = 0;
164
+ let loopCount = 0;
165
+ const nextPromises = [];
166
+ const iterator = prefetcher[Symbol.asyncIterator]();
167
+ for (let i = 0; i < max + 1; i++) {
168
+ nextPromises.push(iterator.next());
169
+ }
170
+ // Wait for all the readers to resolve
171
+ yield Promise.all(nextPromises);
172
+ try {
173
+ for (var _m = true, nextPromises_1 = tslib_1.__asyncValues(nextPromises), nextPromises_1_1; nextPromises_1_1 = yield nextPromises_1.next(), _j = nextPromises_1_1.done, !_j;) {
174
+ _l = nextPromises_1_1.value;
175
+ _m = false;
176
+ try {
177
+ const item = _l;
178
+ if (item.done === true) {
179
+ break;
180
+ }
181
+ loopCount++;
182
+ if (item.value > lastTotal) {
183
+ lastTotal = item.value;
184
+ }
185
+ }
186
+ finally {
187
+ _m = true;
188
+ }
189
+ }
190
+ }
191
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
192
+ finally {
193
+ try {
194
+ if (!_m && !_j && (_k = nextPromises_1.return)) yield _k.call(nextPromises_1);
195
+ }
196
+ finally { if (e_3) throw e_3.error; }
197
+ }
198
+ expect(callCount).toBe(max);
199
+ expect(loopCount).toBe(max);
200
+ expect(total).toBe((max * (max + 1)) / 2);
201
+ expect(lastTotal).toBe((max * (max + 1)) / 2);
202
+ }));
203
+ it('right number run in parallel - simple', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
204
+ var _o, e_4, _p, _q;
205
+ const startTime = Date.now();
206
+ const max = 8;
207
+ const delayBetweenMs = 200;
208
+ const input = [
209
+ { value: 1, ms: delayBetweenMs },
210
+ { value: 2, ms: delayBetweenMs },
211
+ { value: 3, ms: delayBetweenMs },
212
+ { value: 4, ms: delayBetweenMs },
213
+ { value: 5, ms: delayBetweenMs },
214
+ { value: 6, ms: delayBetweenMs },
215
+ { value: 7, ms: delayBetweenMs },
216
+ { value: 8, ms: delayBetweenMs },
217
+ ];
218
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, mapper, { concurrency: 2, maxUnread: 4 });
219
+ let lastSeen = 0;
220
+ let loopCount = 0;
221
+ try {
222
+ for (var _r = true, prefetcher_3 = tslib_1.__asyncValues(prefetcher), prefetcher_3_1; prefetcher_3_1 = yield prefetcher_3.next(), _o = prefetcher_3_1.done, !_o;) {
223
+ _q = prefetcher_3_1.value;
224
+ _r = false;
225
+ try {
226
+ const item = _q;
227
+ loopCount++;
228
+ if (item > lastSeen) {
229
+ lastSeen = item;
230
+ }
231
+ }
232
+ finally {
233
+ _r = true;
234
+ }
235
+ }
236
+ }
237
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
238
+ finally {
239
+ try {
240
+ if (!_r && !_o && (_p = prefetcher_3.return)) yield _p.call(prefetcher_3);
241
+ }
242
+ finally { if (e_4) throw e_4.error; }
243
+ }
244
+ expect(loopCount).toBe(max);
245
+ expect(lastSeen).toBe(max);
246
+ // Should require at least 2 batches
247
+ expect(Date.now() - startTime).toBeLessThan(5 * delayBetweenMs);
248
+ expect(Date.now() - startTime).toBeGreaterThan(4 * delayBetweenMs);
249
+ // The runners should never stop because the items are consumed immediately
250
+ expect(startAnotherRunnerSpy).toHaveBeenCalledTimes(0);
251
+ }));
252
+ // T0 - Mapping - Start 1, 2, waiting 200 ms
253
+ // Q: []
254
+ // Runners - 2 running
255
+ // T200 - Mapping - Finished 1, 2
256
+ // Q: [1, 2]
257
+ // Iterate - Start 1, waiting 300 ms
258
+ // Q: [2]
259
+ // Mapping - Start 3, 4, waiting 200 ms
260
+ // T400 - Mapping - Finished 3, 4
261
+ // Q: [2, 3, 4]
262
+ // Runners - 1 exits, 1 running
263
+ // Mapping - Start 5, waiting 200 ms
264
+ // T500 - Iterate - Start 2, waiting 300 ms
265
+ // Q: [3, 4]
266
+ // Runners - ***1 starts, 2 running after
267
+ // Mapping - Start 6, waiting 200 ms
268
+ // T600 - Mapping - Finished 5
269
+ // Q: [3, 4, 5]
270
+ // Runners - 1 exits, 1 running after
271
+ // T700 - Mapping - Finished 6
272
+ // Q: [3, 4, 5, 6]
273
+ // Runners - 1 exits, 0 running after
274
+ // T800 - Iterate - Finished 2
275
+ // Iterate - Start 3, waiting 300 ms
276
+ // Q: [4, 5, 6]
277
+ // Runners - ***1 starts, 1 running after
278
+ // Mapping - Start 7, waiting 200 ms
279
+ // T1000 - Mapping - Finished 7
280
+ // Q: [4, 5, 6, 7]
281
+ // Runners - 1 exits, 0 running after
282
+ // T1100 - Iterate - Finished 3
283
+ // Iterate - Start 4, waiting 300 ms
284
+ // Q: [5, 6, 7]
285
+ // Runners - ***1 starts, 1 running after
286
+ // T1101 - Mapping - Iteration Done
287
+ // Runners - 1 exits, 0 running after
288
+ // Q: [5, 6, 7]
289
+ // T1400 - Iterate - Finished 4
290
+ // Iterate - Start 5, waiting 300 ms
291
+ // Q: [6, 7]
292
+ // T1700 - Iterate - Finished 5
293
+ // Iterate - Start 6, waiting 300 ms
294
+ // Q: [7]
295
+ // T2000 - Iterate - Finished 6
296
+ // Iterate - Start 7, waiting 300 ms
297
+ // Q: []
298
+ // T2300 - Iterate - Finished 7
299
+ // Q: []
300
+ it('right number run in parallel - delay in reading', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
301
+ var _s, e_5, _t, _u;
302
+ const startTime = Date.now();
303
+ const max = 7;
304
+ const mapDelayMs = 200;
305
+ const readDelayMs = 300;
306
+ const input = [
307
+ { value: 1, ms: mapDelayMs },
308
+ { value: 2, ms: mapDelayMs },
309
+ { value: 3, ms: mapDelayMs },
310
+ { value: 4, ms: mapDelayMs },
311
+ { value: 5, ms: mapDelayMs },
312
+ { value: 6, ms: mapDelayMs },
313
+ { value: 7, ms: mapDelayMs },
314
+ ];
315
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
316
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, mapper, { concurrency: 2, maxUnread: 4 });
317
+ let lastSeen = 0;
318
+ let loopCount = 0;
319
+ try {
320
+ for (var _v = true, prefetcher_4 = tslib_1.__asyncValues(prefetcher), prefetcher_4_1; prefetcher_4_1 = yield prefetcher_4.next(), _s = prefetcher_4_1.done, !_s;) {
321
+ _u = prefetcher_4_1.value;
322
+ _v = false;
323
+ try {
324
+ const item = _u;
325
+ loopCount++;
326
+ if (item > lastSeen) {
327
+ lastSeen = item;
328
+ }
329
+ yield sleep(readDelayMs);
330
+ }
331
+ finally {
332
+ _v = true;
333
+ }
334
+ }
335
+ }
336
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
337
+ finally {
338
+ try {
339
+ if (!_v && !_s && (_t = prefetcher_4.return)) yield _t.call(prefetcher_4);
340
+ }
341
+ finally { if (e_5) throw e_5.error; }
342
+ }
343
+ expect(loopCount).toBe(max);
344
+ expect(lastSeen).toBe(max);
345
+ // 1st we wait 1 mapDelayMs for the 1st item to be ready
346
+ // Then, as we iterate the mapped items, we wait readDelayMs for "processing"
347
+ // This means that all the subsequent mapper calls never delay us because the
348
+ // prefetch queue is always full.
349
+ // Because of the prime numbers (2, 3, and 7) we know that we didn't accidentally
350
+ // cause delays of a multiple of the wrong number.
351
+ expect(Date.now() - startTime).toBeGreaterThan(mapDelayMs + max * readDelayMs);
352
+ expect(sourceNextSpy).toHaveBeenCalledTimes(max + 1);
353
+ expect(startAnotherRunnerSpy).toHaveBeenCalledTimes(3);
354
+ }));
355
+ });
356
+ describe('empty iterables', () => {
357
+ it('empty sync iterable works - sync mapper', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
358
+ var _a, e_6, _b, _c;
359
+ let total = 0;
360
+ let callCount = 0;
361
+ const prefetcher = new iterable_mapper_1.IterableMapper([], (value) => {
362
+ callCount++;
363
+ total += value;
364
+ return total;
365
+ });
366
+ let lastTotal = 0;
367
+ let loopCount = 0;
368
+ try {
369
+ for (var _d = true, prefetcher_5 = tslib_1.__asyncValues(prefetcher), prefetcher_5_1; prefetcher_5_1 = yield prefetcher_5.next(), _a = prefetcher_5_1.done, !_a;) {
370
+ _c = prefetcher_5_1.value;
371
+ _d = false;
372
+ try {
373
+ const item = _c;
374
+ loopCount++;
375
+ if (item > lastTotal) {
376
+ lastTotal = item;
377
+ }
378
+ }
379
+ finally {
380
+ _d = true;
381
+ }
382
+ }
383
+ }
384
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
385
+ finally {
386
+ try {
387
+ if (!_d && !_a && (_b = prefetcher_5.return)) yield _b.call(prefetcher_5);
388
+ }
389
+ finally { if (e_6) throw e_6.error; }
390
+ }
391
+ expect(callCount).toBe(0);
392
+ expect(loopCount).toBe(0);
393
+ expect(total).toBe(0);
394
+ expect(lastTotal).toBe(0);
395
+ }));
396
+ it('empty sync iterable works - async mapper', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
397
+ var _e, e_7, _f, _g;
398
+ let total = 0;
399
+ let callCount = 0;
400
+ const prefetcher = new iterable_mapper_1.IterableMapper([], (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
401
+ yield sleep(10);
402
+ callCount++;
403
+ total += value;
404
+ return total;
405
+ }));
406
+ let lastTotal = 0;
407
+ let loopCount = 0;
408
+ try {
409
+ for (var _h = true, prefetcher_6 = tslib_1.__asyncValues(prefetcher), prefetcher_6_1; prefetcher_6_1 = yield prefetcher_6.next(), _e = prefetcher_6_1.done, !_e;) {
410
+ _g = prefetcher_6_1.value;
411
+ _h = false;
412
+ try {
413
+ const item = _g;
414
+ loopCount++;
415
+ if (item > lastTotal) {
416
+ lastTotal = item;
417
+ }
418
+ }
419
+ finally {
420
+ _h = true;
421
+ }
422
+ }
423
+ }
424
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
425
+ finally {
426
+ try {
427
+ if (!_h && !_e && (_f = prefetcher_6.return)) yield _f.call(prefetcher_6);
428
+ }
429
+ finally { if (e_7) throw e_7.error; }
430
+ }
431
+ expect(callCount).toBe(0);
432
+ expect(loopCount).toBe(0);
433
+ expect(total).toBe(0);
434
+ expect(lastTotal).toBe(0);
435
+ }));
436
+ it('empty async iterable works - sync mapper', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
437
+ var _j, e_8, _k, _l;
438
+ let total = 0;
439
+ let callCount = 0;
440
+ const prefetcher = new iterable_mapper_1.IterableMapper((() => {
441
+ return {
442
+ [Symbol.asyncIterator]() {
443
+ return {
444
+ next() {
445
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
446
+ yield sleep(100);
447
+ return { value: undefined, done: true };
448
+ });
449
+ },
450
+ };
451
+ },
452
+ };
453
+ })(), (value) => {
454
+ callCount++;
455
+ total += value;
456
+ return total;
457
+ });
458
+ let lastTotal = 0;
459
+ let loopCount = 0;
460
+ try {
461
+ for (var _m = true, prefetcher_7 = tslib_1.__asyncValues(prefetcher), prefetcher_7_1; prefetcher_7_1 = yield prefetcher_7.next(), _j = prefetcher_7_1.done, !_j;) {
462
+ _l = prefetcher_7_1.value;
463
+ _m = false;
464
+ try {
465
+ const item = _l;
466
+ loopCount++;
467
+ if (item > lastTotal) {
468
+ lastTotal = item;
469
+ }
470
+ }
471
+ finally {
472
+ _m = true;
473
+ }
474
+ }
475
+ }
476
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
477
+ finally {
478
+ try {
479
+ if (!_m && !_j && (_k = prefetcher_7.return)) yield _k.call(prefetcher_7);
480
+ }
481
+ finally { if (e_8) throw e_8.error; }
482
+ }
483
+ expect(callCount).toBe(0);
484
+ expect(loopCount).toBe(0);
485
+ expect(total).toBe(0);
486
+ expect(lastTotal).toBe(0);
487
+ }));
488
+ it('empty async iterable works - async mapper', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
489
+ var _o, e_9, _p, _q;
490
+ let total = 0;
491
+ let callCount = 0;
492
+ const prefetcher = new iterable_mapper_1.IterableMapper((() => {
493
+ return {
494
+ [Symbol.asyncIterator]() {
495
+ return {
496
+ next() {
497
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
498
+ yield sleep(100);
499
+ return { value: undefined, done: true };
500
+ });
501
+ },
502
+ };
503
+ },
504
+ };
505
+ })(), (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
506
+ yield sleep(10);
507
+ callCount++;
508
+ total += value;
509
+ return total;
510
+ }));
511
+ let lastTotal = 0;
512
+ let loopCount = 0;
513
+ try {
514
+ for (var _r = true, prefetcher_8 = tslib_1.__asyncValues(prefetcher), prefetcher_8_1; prefetcher_8_1 = yield prefetcher_8.next(), _o = prefetcher_8_1.done, !_o;) {
515
+ _q = prefetcher_8_1.value;
516
+ _r = false;
517
+ try {
518
+ const item = _q;
519
+ loopCount++;
520
+ if (item > lastTotal) {
521
+ lastTotal = item;
522
+ }
523
+ }
524
+ finally {
525
+ _r = true;
526
+ }
527
+ }
528
+ }
529
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
530
+ finally {
531
+ try {
532
+ if (!_r && !_o && (_p = prefetcher_8.return)) yield _p.call(prefetcher_8);
533
+ }
534
+ finally { if (e_9) throw e_9.error; }
535
+ }
536
+ expect(callCount).toBe(0);
537
+ expect(loopCount).toBe(0);
538
+ expect(total).toBe(0);
539
+ expect(lastTotal).toBe(0);
540
+ }));
541
+ });
542
+ describe('concurrency 1, maxUnread 1', () => {
543
+ const concurrency = 1;
544
+ const maxUnread = 1;
545
+ it('catches exception from mapper - 1st item - stopOnMapperError true', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
546
+ const input = [1, () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return sleep(300, 2); }), 3];
547
+ const mappedValues = [];
548
+ const iteratedValues = [];
549
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
550
+ value = typeof value === 'function' ? yield value() : value;
551
+ mappedValues.push(value);
552
+ if (value === 1) {
553
+ yield sleep(100);
554
+ throw new Error('throw on 1st');
555
+ }
556
+ return value;
557
+ }), { concurrency, maxUnread });
558
+ let loopCount = 0;
559
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
560
+ var _a, e_10, _b, _c;
561
+ try {
562
+ for (var _d = true, prefetcher_9 = tslib_1.__asyncValues(prefetcher), prefetcher_9_1; prefetcher_9_1 = yield prefetcher_9.next(), _a = prefetcher_9_1.done, !_a;) {
563
+ _c = prefetcher_9_1.value;
564
+ _d = false;
565
+ try {
566
+ const value = _c;
567
+ loopCount++;
568
+ iteratedValues.push(value);
569
+ }
570
+ finally {
571
+ _d = true;
572
+ }
573
+ }
574
+ }
575
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
576
+ finally {
577
+ try {
578
+ if (!_d && !_a && (_b = prefetcher_9.return)) yield _b.call(prefetcher_9);
579
+ }
580
+ finally { if (e_10) throw e_10.error; }
581
+ }
582
+ })).rejects.toThrowError('throw on 1st');
583
+ yield sleep(500);
584
+ expect(loopCount).toBe(0);
585
+ expect(mappedValues).toEqual([1]);
586
+ expect(iteratedValues).toEqual([]);
587
+ }));
588
+ it('catches exception from mapper - 2nd item - stopOnMapperError true', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
589
+ const input = [1, () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return sleep(300, 2); }), 3];
590
+ const mappedValues = [];
591
+ const iteratedValues = [];
592
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
593
+ value = typeof value === 'function' ? yield value() : value;
594
+ mappedValues.push(value);
595
+ if (value === 2) {
596
+ throw new Error('throw on 2nd');
597
+ }
598
+ yield sleep(100);
599
+ return value;
600
+ }), { concurrency, maxUnread });
601
+ let loopCount = 0;
602
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
603
+ var _e, e_11, _f, _g;
604
+ try {
605
+ for (var _h = true, prefetcher_10 = tslib_1.__asyncValues(prefetcher), prefetcher_10_1; prefetcher_10_1 = yield prefetcher_10.next(), _e = prefetcher_10_1.done, !_e;) {
606
+ _g = prefetcher_10_1.value;
607
+ _h = false;
608
+ try {
609
+ const value = _g;
610
+ loopCount++;
611
+ iteratedValues.push(value);
612
+ }
613
+ finally {
614
+ _h = true;
615
+ }
616
+ }
617
+ }
618
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
619
+ finally {
620
+ try {
621
+ if (!_h && !_e && (_f = prefetcher_10.return)) yield _f.call(prefetcher_10);
622
+ }
623
+ finally { if (e_11) throw e_11.error; }
624
+ }
625
+ })).rejects.toThrowError('throw on 2nd');
626
+ yield sleep(300);
627
+ expect(loopCount).toBe(1);
628
+ expect(mappedValues).toEqual([1, 2]);
629
+ expect(iteratedValues).toEqual([1]);
630
+ }));
631
+ it('catches exception from mapper - 1st item - stopOnMapperError false', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
632
+ const input = [1, () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return sleep(300, 2); }), 3];
633
+ const mappedValues = [];
634
+ const iteratedValues = [];
635
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
636
+ value = typeof value === 'function' ? yield value() : value;
637
+ mappedValues.push(value);
638
+ if (value === 1) {
639
+ throw new Error('throw on 1st');
640
+ }
641
+ yield sleep(100);
642
+ return value;
643
+ }), { concurrency: 1, stopOnMapperError: false });
644
+ let loopCount = 0;
645
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
646
+ var _j, e_12, _k, _l;
647
+ try {
648
+ for (var _m = true, prefetcher_11 = tslib_1.__asyncValues(prefetcher), prefetcher_11_1; prefetcher_11_1 = yield prefetcher_11.next(), _j = prefetcher_11_1.done, !_j;) {
649
+ _l = prefetcher_11_1.value;
650
+ _m = false;
651
+ try {
652
+ const value = _l;
653
+ loopCount++;
654
+ iteratedValues.push(value);
655
+ }
656
+ finally {
657
+ _m = true;
658
+ }
659
+ }
660
+ }
661
+ catch (e_12_1) { e_12 = { error: e_12_1 }; }
662
+ finally {
663
+ try {
664
+ if (!_m && !_j && (_k = prefetcher_11.return)) yield _k.call(prefetcher_11);
665
+ }
666
+ finally { if (e_12) throw e_12.error; }
667
+ }
668
+ })).rejects.toThrowError('throw on 1st');
669
+ yield sleep(300);
670
+ expect(loopCount).toBe(2);
671
+ expect(mappedValues).toEqual([1, 2, 3]);
672
+ expect(iteratedValues).toEqual([2, 3]);
673
+ }));
674
+ it('catches exception from mapper - 2nd item - stopOnMapperError false', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
675
+ const input = [1, () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return sleep(300, 2); }), 3];
676
+ const mappedValues = [];
677
+ const iteratedValues = [];
678
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
679
+ value = typeof value === 'function' ? yield value() : value;
680
+ mappedValues.push(value);
681
+ if (value === 2) {
682
+ throw new Error('throw on 2nd');
683
+ }
684
+ yield sleep(100);
685
+ return value;
686
+ }), { concurrency, maxUnread, stopOnMapperError: false });
687
+ let loopCount = 0;
688
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
689
+ var _o, e_13, _p, _q;
690
+ try {
691
+ for (var _r = true, prefetcher_12 = tslib_1.__asyncValues(prefetcher), prefetcher_12_1; prefetcher_12_1 = yield prefetcher_12.next(), _o = prefetcher_12_1.done, !_o;) {
692
+ _q = prefetcher_12_1.value;
693
+ _r = false;
694
+ try {
695
+ const value = _q;
696
+ loopCount++;
697
+ iteratedValues.push(value);
698
+ }
699
+ finally {
700
+ _r = true;
701
+ }
702
+ }
703
+ }
704
+ catch (e_13_1) { e_13 = { error: e_13_1 }; }
705
+ finally {
706
+ try {
707
+ if (!_r && !_o && (_p = prefetcher_12.return)) yield _p.call(prefetcher_12);
708
+ }
709
+ finally { if (e_13) throw e_13.error; }
710
+ }
711
+ })).rejects.toThrowError('throw on 2nd');
712
+ yield sleep(300);
713
+ expect(loopCount).toBe(2);
714
+ expect(mappedValues).toEqual([1, 2, 3]);
715
+ expect(iteratedValues).toEqual([1, 3]);
716
+ }));
717
+ it('catches exception from mapper - 10 of 10 items - stopOnMapperError false', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
718
+ const input = new SleepIterator(10);
719
+ const mappedValues = [];
720
+ const iteratedValues = [];
721
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => {
722
+ mappedValues.push(value);
723
+ throw new Error('throw on each');
724
+ }, { concurrency, maxUnread, stopOnMapperError: false });
725
+ let loopCount = 0;
726
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
727
+ var _s, e_14, _t, _u;
728
+ try {
729
+ for (var _v = true, prefetcher_13 = tslib_1.__asyncValues(prefetcher), prefetcher_13_1; prefetcher_13_1 = yield prefetcher_13.next(), _s = prefetcher_13_1.done, !_s;) {
730
+ _u = prefetcher_13_1.value;
731
+ _v = false;
732
+ try {
733
+ const value = _u;
734
+ loopCount++;
735
+ iteratedValues.push(value);
736
+ }
737
+ finally {
738
+ _v = true;
739
+ }
740
+ }
741
+ }
742
+ catch (e_14_1) { e_14 = { error: e_14_1 }; }
743
+ finally {
744
+ try {
745
+ if (!_v && !_s && (_t = prefetcher_13.return)) yield _t.call(prefetcher_13);
746
+ }
747
+ finally { if (e_14) throw e_14.error; }
748
+ }
749
+ })).rejects.toThrowError('throw on each');
750
+ expect(loopCount).toBe(0);
751
+ expect(mappedValues).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
752
+ expect(iteratedValues).toEqual([]);
753
+ }));
754
+ it('catches exception from mapper - 10 of 10 items - stopOnMapperError true', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
755
+ const input = new SleepIterator(10);
756
+ const mappedValues = [];
757
+ const iteratedValues = [];
758
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => {
759
+ mappedValues.push(value);
760
+ throw new Error('throw on each');
761
+ }, { concurrency, maxUnread, stopOnMapperError: true });
762
+ let loopCount = 0;
763
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
764
+ var _w, e_15, _x, _y;
765
+ try {
766
+ for (var _z = true, prefetcher_14 = tslib_1.__asyncValues(prefetcher), prefetcher_14_1; prefetcher_14_1 = yield prefetcher_14.next(), _w = prefetcher_14_1.done, !_w;) {
767
+ _y = prefetcher_14_1.value;
768
+ _z = false;
769
+ try {
770
+ const value = _y;
771
+ loopCount++;
772
+ iteratedValues.push(value);
773
+ }
774
+ finally {
775
+ _z = true;
776
+ }
777
+ }
778
+ }
779
+ catch (e_15_1) { e_15 = { error: e_15_1 }; }
780
+ finally {
781
+ try {
782
+ if (!_z && !_w && (_x = prefetcher_14.return)) yield _x.call(prefetcher_14);
783
+ }
784
+ finally { if (e_15) throw e_15.error; }
785
+ }
786
+ })).rejects.toThrowError('throw on each');
787
+ expect(loopCount).toBe(0);
788
+ expect(mappedValues).toEqual([1]);
789
+ expect(iteratedValues).toEqual([]);
790
+ }));
791
+ it('catches exception from source iterator - 1st item', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
792
+ const input = new ThrowingIterator(100, 0, 100);
793
+ const mappedValues = [];
794
+ const iteratedValues = [];
795
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
796
+ mappedValues.push(value);
797
+ yield sleep(100);
798
+ return value;
799
+ }), { concurrency, maxUnread, stopOnMapperError: false });
800
+ let loopCount = 0;
801
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
802
+ var _0, e_16, _1, _2;
803
+ try {
804
+ for (var _3 = true, prefetcher_15 = tslib_1.__asyncValues(prefetcher), prefetcher_15_1; prefetcher_15_1 = yield prefetcher_15.next(), _0 = prefetcher_15_1.done, !_0;) {
805
+ _2 = prefetcher_15_1.value;
806
+ _3 = false;
807
+ try {
808
+ const value = _2;
809
+ loopCount++;
810
+ iteratedValues.push(value);
811
+ }
812
+ finally {
813
+ _3 = true;
814
+ }
815
+ }
816
+ }
817
+ catch (e_16_1) { e_16 = { error: e_16_1 }; }
818
+ finally {
819
+ try {
820
+ if (!_3 && !_0 && (_1 = prefetcher_15.return)) yield _1.call(prefetcher_15);
821
+ }
822
+ finally { if (e_16) throw e_16.error; }
823
+ }
824
+ })).rejects.toThrowError('throwing on index 0');
825
+ yield sleep(500);
826
+ expect(loopCount).toBe(0);
827
+ expect(mappedValues).toEqual([]);
828
+ expect(iteratedValues).toEqual([]);
829
+ }));
830
+ // The 2nd iterable item throwing is distinct from the 1st when concurrency is 1 because
831
+ // it means that the sourceNext() is invoked from next() or sourceNext() and not from
832
+ // the constructor
833
+ it('catches exception from source iterator - 2nd item', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
834
+ const input = new ThrowingIterator(100, 1, 100);
835
+ const mappedValues = [];
836
+ const iteratedValues = [];
837
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
838
+ mappedValues.push(value);
839
+ yield sleep(100);
840
+ return value;
841
+ }), { concurrency, maxUnread, stopOnMapperError: false });
842
+ let loopCount = 0;
843
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
844
+ var _4, e_17, _5, _6;
845
+ try {
846
+ for (var _7 = true, prefetcher_16 = tslib_1.__asyncValues(prefetcher), prefetcher_16_1; prefetcher_16_1 = yield prefetcher_16.next(), _4 = prefetcher_16_1.done, !_4;) {
847
+ _6 = prefetcher_16_1.value;
848
+ _7 = false;
849
+ try {
850
+ const value = _6;
851
+ loopCount++;
852
+ iteratedValues.push(value);
853
+ }
854
+ finally {
855
+ _7 = true;
856
+ }
857
+ }
858
+ }
859
+ catch (e_17_1) { e_17 = { error: e_17_1 }; }
860
+ finally {
861
+ try {
862
+ if (!_7 && !_4 && (_5 = prefetcher_16.return)) yield _5.call(prefetcher_16);
863
+ }
864
+ finally { if (e_17) throw e_17.error; }
865
+ }
866
+ })).rejects.toThrowError('throwing on index 1');
867
+ yield sleep(500);
868
+ expect(loopCount).toBe(1);
869
+ expect(mappedValues).toEqual([0]);
870
+ expect(iteratedValues).toEqual([0]);
871
+ }));
872
+ });
873
+ describe('concurrency 2, maxUnread 4', () => {
874
+ const concurrency = 2;
875
+ const maxUnread = 4;
876
+ it('catches exception from mapper - 1st item - stopOnMapperError true', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
877
+ const input = [1, () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return sleep(300, 2); }), 3];
878
+ const mappedValues = [];
879
+ const iteratedValues = [];
880
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
881
+ value = typeof value === 'function' ? yield value() : value;
882
+ mappedValues.push(value);
883
+ if (value === 1) {
884
+ yield sleep(100);
885
+ throw new Error('throw on 1st');
886
+ }
887
+ return value;
888
+ }), { concurrency, maxUnread });
889
+ let loopCount = 0;
890
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
891
+ var _a, e_18, _b, _c;
892
+ try {
893
+ for (var _d = true, prefetcher_17 = tslib_1.__asyncValues(prefetcher), prefetcher_17_1; prefetcher_17_1 = yield prefetcher_17.next(), _a = prefetcher_17_1.done, !_a;) {
894
+ _c = prefetcher_17_1.value;
895
+ _d = false;
896
+ try {
897
+ const value = _c;
898
+ loopCount++;
899
+ iteratedValues.push(value);
900
+ }
901
+ finally {
902
+ _d = true;
903
+ }
904
+ }
905
+ }
906
+ catch (e_18_1) { e_18 = { error: e_18_1 }; }
907
+ finally {
908
+ try {
909
+ if (!_d && !_a && (_b = prefetcher_17.return)) yield _b.call(prefetcher_17);
910
+ }
911
+ finally { if (e_18) throw e_18.error; }
912
+ }
913
+ })).rejects.toThrowError('throw on 1st');
914
+ yield sleep(500);
915
+ expect(loopCount).toBe(0);
916
+ expect(mappedValues).toEqual([1, 2]);
917
+ expect(iteratedValues).toEqual([]);
918
+ }));
919
+ it('catches exception from mapper - 2nd item - stopOnMapperError true', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
920
+ const input = [1, () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return sleep(300, 2); }), 3];
921
+ const mappedValues = [];
922
+ const iteratedValues = [];
923
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
924
+ value = typeof value === 'function' ? yield value() : value;
925
+ mappedValues.push(value);
926
+ if (value === 2) {
927
+ throw new Error('throw on 2nd');
928
+ }
929
+ yield sleep(100);
930
+ return value;
931
+ }), { concurrency, maxUnread });
932
+ let loopCount = 0;
933
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
934
+ var _e, e_19, _f, _g;
935
+ try {
936
+ for (var _h = true, prefetcher_18 = tslib_1.__asyncValues(prefetcher), prefetcher_18_1; prefetcher_18_1 = yield prefetcher_18.next(), _e = prefetcher_18_1.done, !_e;) {
937
+ _g = prefetcher_18_1.value;
938
+ _h = false;
939
+ try {
940
+ const value = _g;
941
+ loopCount++;
942
+ iteratedValues.push(value);
943
+ }
944
+ finally {
945
+ _h = true;
946
+ }
947
+ }
948
+ }
949
+ catch (e_19_1) { e_19 = { error: e_19_1 }; }
950
+ finally {
951
+ try {
952
+ if (!_h && !_e && (_f = prefetcher_18.return)) yield _f.call(prefetcher_18);
953
+ }
954
+ finally { if (e_19) throw e_19.error; }
955
+ }
956
+ })).rejects.toThrowError('throw on 2nd');
957
+ yield sleep(300);
958
+ expect(loopCount).toBe(2);
959
+ expect(mappedValues).toEqual([1, 3, 2]);
960
+ expect(iteratedValues).toEqual([1, 3]);
961
+ }));
962
+ it('catches exception from mapper - 1st item - stopOnMapperError false', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
963
+ const input = [1, () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return sleep(300, 2); }), 3];
964
+ const mappedValues = [];
965
+ const iteratedValues = [];
966
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
967
+ value = typeof value === 'function' ? yield value() : value;
968
+ mappedValues.push(value);
969
+ if (value === 1) {
970
+ throw new Error('throw on 1st');
971
+ }
972
+ yield sleep(100);
973
+ return value;
974
+ }), { concurrency, maxUnread, stopOnMapperError: false });
975
+ let loopCount = 0;
976
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
977
+ var _j, e_20, _k, _l;
978
+ try {
979
+ for (var _m = true, prefetcher_19 = tslib_1.__asyncValues(prefetcher), prefetcher_19_1; prefetcher_19_1 = yield prefetcher_19.next(), _j = prefetcher_19_1.done, !_j;) {
980
+ _l = prefetcher_19_1.value;
981
+ _m = false;
982
+ try {
983
+ const value = _l;
984
+ loopCount++;
985
+ iteratedValues.push(value);
986
+ }
987
+ finally {
988
+ _m = true;
989
+ }
990
+ }
991
+ }
992
+ catch (e_20_1) { e_20 = { error: e_20_1 }; }
993
+ finally {
994
+ try {
995
+ if (!_m && !_j && (_k = prefetcher_19.return)) yield _k.call(prefetcher_19);
996
+ }
997
+ finally { if (e_20) throw e_20.error; }
998
+ }
999
+ })).rejects.toThrowError('throw on 1st');
1000
+ yield sleep(300);
1001
+ expect(loopCount).toBe(2);
1002
+ expect(mappedValues).toEqual([1, 3, 2]);
1003
+ expect(iteratedValues).toEqual([3, 2]);
1004
+ }));
1005
+ it('catches exception from mapper - 2nd item - stopOnMapperError false', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1006
+ const input = [1, () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return sleep(300, 2); }), 3];
1007
+ const mappedValues = [];
1008
+ const iteratedValues = [];
1009
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1010
+ value = typeof value === 'function' ? yield value() : value;
1011
+ mappedValues.push(value);
1012
+ if (value === 2) {
1013
+ throw new Error('throw on 2nd');
1014
+ }
1015
+ yield sleep(100);
1016
+ return value;
1017
+ }), { concurrency, maxUnread, stopOnMapperError: false });
1018
+ let loopCount = 0;
1019
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1020
+ var _o, e_21, _p, _q;
1021
+ try {
1022
+ for (var _r = true, prefetcher_20 = tslib_1.__asyncValues(prefetcher), prefetcher_20_1; prefetcher_20_1 = yield prefetcher_20.next(), _o = prefetcher_20_1.done, !_o;) {
1023
+ _q = prefetcher_20_1.value;
1024
+ _r = false;
1025
+ try {
1026
+ const value = _q;
1027
+ loopCount++;
1028
+ iteratedValues.push(value);
1029
+ }
1030
+ finally {
1031
+ _r = true;
1032
+ }
1033
+ }
1034
+ }
1035
+ catch (e_21_1) { e_21 = { error: e_21_1 }; }
1036
+ finally {
1037
+ try {
1038
+ if (!_r && !_o && (_p = prefetcher_20.return)) yield _p.call(prefetcher_20);
1039
+ }
1040
+ finally { if (e_21) throw e_21.error; }
1041
+ }
1042
+ })).rejects.toThrowError('throw on 2nd');
1043
+ yield sleep(300);
1044
+ expect(loopCount).toBe(2);
1045
+ expect(mappedValues).toEqual([1, 3, 2]);
1046
+ expect(iteratedValues).toEqual([1, 3]);
1047
+ }));
1048
+ it('catches exception from mapper - 10 of 10 items - stopOnMapperError false', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1049
+ const input = new SleepIterator(10);
1050
+ const mappedValues = [];
1051
+ const iteratedValues = [];
1052
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => {
1053
+ mappedValues.push(value);
1054
+ throw new Error('throw on each');
1055
+ }, { concurrency, maxUnread, stopOnMapperError: false });
1056
+ let loopCount = 0;
1057
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1058
+ var _s, e_22, _t, _u;
1059
+ try {
1060
+ for (var _v = true, prefetcher_21 = tslib_1.__asyncValues(prefetcher), prefetcher_21_1; prefetcher_21_1 = yield prefetcher_21.next(), _s = prefetcher_21_1.done, !_s;) {
1061
+ _u = prefetcher_21_1.value;
1062
+ _v = false;
1063
+ try {
1064
+ const value = _u;
1065
+ loopCount++;
1066
+ iteratedValues.push(value);
1067
+ }
1068
+ finally {
1069
+ _v = true;
1070
+ }
1071
+ }
1072
+ }
1073
+ catch (e_22_1) { e_22 = { error: e_22_1 }; }
1074
+ finally {
1075
+ try {
1076
+ if (!_v && !_s && (_t = prefetcher_21.return)) yield _t.call(prefetcher_21);
1077
+ }
1078
+ finally { if (e_22) throw e_22.error; }
1079
+ }
1080
+ })).rejects.toThrowError('throw on each');
1081
+ expect(loopCount).toBe(0);
1082
+ expect(mappedValues).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
1083
+ expect(iteratedValues).toEqual([]);
1084
+ }));
1085
+ it('catches exception from mapper - 10 of 10 items - stopOnMapperError true', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1086
+ const input = new SleepIterator(10);
1087
+ const mappedValues = [];
1088
+ const iteratedValues = [];
1089
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => {
1090
+ mappedValues.push(value);
1091
+ throw new Error('throw on each');
1092
+ }, { concurrency, maxUnread, stopOnMapperError: true });
1093
+ let loopCount = 0;
1094
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1095
+ var _w, e_23, _x, _y;
1096
+ try {
1097
+ for (var _z = true, prefetcher_22 = tslib_1.__asyncValues(prefetcher), prefetcher_22_1; prefetcher_22_1 = yield prefetcher_22.next(), _w = prefetcher_22_1.done, !_w;) {
1098
+ _y = prefetcher_22_1.value;
1099
+ _z = false;
1100
+ try {
1101
+ const value = _y;
1102
+ loopCount++;
1103
+ iteratedValues.push(value);
1104
+ }
1105
+ finally {
1106
+ _z = true;
1107
+ }
1108
+ }
1109
+ }
1110
+ catch (e_23_1) { e_23 = { error: e_23_1 }; }
1111
+ finally {
1112
+ try {
1113
+ if (!_z && !_w && (_x = prefetcher_22.return)) yield _x.call(prefetcher_22);
1114
+ }
1115
+ finally { if (e_23) throw e_23.error; }
1116
+ }
1117
+ })).rejects.toThrowError('throw on each');
1118
+ expect(loopCount).toBe(0);
1119
+ expect(mappedValues).toEqual([1]);
1120
+ expect(iteratedValues).toEqual([]);
1121
+ }));
1122
+ it('catches exception from source iterator - 1st item', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1123
+ const input = new ThrowingIterator(100, 0, 100);
1124
+ const mappedValues = [];
1125
+ const iteratedValues = [];
1126
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1127
+ mappedValues.push(value);
1128
+ yield sleep(100);
1129
+ return value;
1130
+ }), { concurrency, maxUnread, stopOnMapperError: false });
1131
+ let loopCount = 0;
1132
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1133
+ var _0, e_24, _1, _2;
1134
+ try {
1135
+ for (var _3 = true, prefetcher_23 = tslib_1.__asyncValues(prefetcher), prefetcher_23_1; prefetcher_23_1 = yield prefetcher_23.next(), _0 = prefetcher_23_1.done, !_0;) {
1136
+ _2 = prefetcher_23_1.value;
1137
+ _3 = false;
1138
+ try {
1139
+ const value = _2;
1140
+ loopCount++;
1141
+ iteratedValues.push(value);
1142
+ }
1143
+ finally {
1144
+ _3 = true;
1145
+ }
1146
+ }
1147
+ }
1148
+ catch (e_24_1) { e_24 = { error: e_24_1 }; }
1149
+ finally {
1150
+ try {
1151
+ if (!_3 && !_0 && (_1 = prefetcher_23.return)) yield _1.call(prefetcher_23);
1152
+ }
1153
+ finally { if (e_24) throw e_24.error; }
1154
+ }
1155
+ })).rejects.toThrowError('throwing on index 0');
1156
+ yield sleep(500);
1157
+ expect(loopCount).toBe(0);
1158
+ expect(mappedValues).toEqual([]);
1159
+ expect(iteratedValues).toEqual([]);
1160
+ }));
1161
+ // The 2nd iterable item throwing is distinct from the 1st when concurrency is 1 because
1162
+ // it means that the sourceNext() is invoked from next() or sourceNext() and not from
1163
+ // the constructor
1164
+ it('catches exception from source iterator - 2nd item', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1165
+ const input = new ThrowingIterator(100, 1, 100);
1166
+ const mappedValues = [];
1167
+ const iteratedValues = [];
1168
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1169
+ mappedValues.push(value);
1170
+ yield sleep(100);
1171
+ return value;
1172
+ }), { concurrency, maxUnread, stopOnMapperError: false });
1173
+ let loopCount = 0;
1174
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1175
+ var _4, e_25, _5, _6;
1176
+ try {
1177
+ for (var _7 = true, prefetcher_24 = tslib_1.__asyncValues(prefetcher), prefetcher_24_1; prefetcher_24_1 = yield prefetcher_24.next(), _4 = prefetcher_24_1.done, !_4;) {
1178
+ _6 = prefetcher_24_1.value;
1179
+ _7 = false;
1180
+ try {
1181
+ const value = _6;
1182
+ loopCount++;
1183
+ iteratedValues.push(value);
1184
+ }
1185
+ finally {
1186
+ _7 = true;
1187
+ }
1188
+ }
1189
+ }
1190
+ catch (e_25_1) { e_25 = { error: e_25_1 }; }
1191
+ finally {
1192
+ try {
1193
+ if (!_7 && !_4 && (_5 = prefetcher_24.return)) yield _5.call(prefetcher_24);
1194
+ }
1195
+ finally { if (e_25) throw e_25.error; }
1196
+ }
1197
+ })).rejects.toThrowError('throwing on index 1');
1198
+ yield sleep(500);
1199
+ expect(loopCount).toBe(1);
1200
+ expect(mappedValues).toEqual([0]);
1201
+ expect(iteratedValues).toEqual([0]);
1202
+ }));
1203
+ });
1204
+ describe('concurrency Number.POSITIVE_INFINITY, maxUnread Number.POSITIVE_INFINITY', () => {
1205
+ const concurrency = Number.POSITIVE_INFINITY;
1206
+ const maxUnread = Number.POSITIVE_INFINITY;
1207
+ it('catches exception from mapper - 1st item - stopOnMapperError true', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1208
+ const input = [1, () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return sleep(300, 2); }), 3];
1209
+ const mappedValues = [];
1210
+ const iteratedValues = [];
1211
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1212
+ value = typeof value === 'function' ? yield value() : value;
1213
+ mappedValues.push(value);
1214
+ if (value === 1) {
1215
+ yield sleep(100);
1216
+ throw new Error('throw on 1st');
1217
+ }
1218
+ return value;
1219
+ }), { concurrency, maxUnread });
1220
+ let loopCount = 0;
1221
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1222
+ var _a, e_26, _b, _c;
1223
+ try {
1224
+ for (var _d = true, prefetcher_25 = tslib_1.__asyncValues(prefetcher), prefetcher_25_1; prefetcher_25_1 = yield prefetcher_25.next(), _a = prefetcher_25_1.done, !_a;) {
1225
+ _c = prefetcher_25_1.value;
1226
+ _d = false;
1227
+ try {
1228
+ const value = _c;
1229
+ loopCount++;
1230
+ iteratedValues.push(value);
1231
+ }
1232
+ finally {
1233
+ _d = true;
1234
+ }
1235
+ }
1236
+ }
1237
+ catch (e_26_1) { e_26 = { error: e_26_1 }; }
1238
+ finally {
1239
+ try {
1240
+ if (!_d && !_a && (_b = prefetcher_25.return)) yield _b.call(prefetcher_25);
1241
+ }
1242
+ finally { if (e_26) throw e_26.error; }
1243
+ }
1244
+ })).rejects.toThrowError('throw on 1st');
1245
+ yield sleep(500);
1246
+ expect(loopCount).toBe(1);
1247
+ expect(mappedValues).toEqual([1, 3, 2]);
1248
+ // NOTE: This seems wrong - Item 2 succeeds at being mapped, but after the 1st item throws.
1249
+ // Since item 2 was mapped you would think it should be iterated with the exception for
1250
+ // item 1 delayed until all items are read.
1251
+ // However, since the mapper for 2 could throw, this could lead to 2 exceptions wanting to
1252
+ // throw if we waited like this... so we would have to throw an AggregateError... and
1253
+ // that just leads to guidance that the caller should catch exceptions in their mapper
1254
+ // and return them as part of their NewElement object type.
1255
+ // If a consumer catches and returns the exception then re-throws in their `for await`
1256
+ // then this behavior would match their results exactly (the 1st item would cause the iteration
1257
+ // loop to break out).
1258
+ expect(iteratedValues).toEqual([3]);
1259
+ }));
1260
+ it('catches exception from mapper - 2nd item - stopOnMapperError true', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1261
+ const input = [1, () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return sleep(300, 2); }), 3];
1262
+ const mappedValues = [];
1263
+ const iteratedValues = [];
1264
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1265
+ value = typeof value === 'function' ? yield value() : value;
1266
+ mappedValues.push(value);
1267
+ if (value === 2) {
1268
+ throw new Error('throw on 2nd');
1269
+ }
1270
+ yield sleep(100);
1271
+ return value;
1272
+ }), { concurrency, maxUnread });
1273
+ let loopCount = 0;
1274
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1275
+ var _e, e_27, _f, _g;
1276
+ try {
1277
+ for (var _h = true, prefetcher_26 = tslib_1.__asyncValues(prefetcher), prefetcher_26_1; prefetcher_26_1 = yield prefetcher_26.next(), _e = prefetcher_26_1.done, !_e;) {
1278
+ _g = prefetcher_26_1.value;
1279
+ _h = false;
1280
+ try {
1281
+ const value = _g;
1282
+ loopCount++;
1283
+ iteratedValues.push(value);
1284
+ }
1285
+ finally {
1286
+ _h = true;
1287
+ }
1288
+ }
1289
+ }
1290
+ catch (e_27_1) { e_27 = { error: e_27_1 }; }
1291
+ finally {
1292
+ try {
1293
+ if (!_h && !_e && (_f = prefetcher_26.return)) yield _f.call(prefetcher_26);
1294
+ }
1295
+ finally { if (e_27) throw e_27.error; }
1296
+ }
1297
+ })).rejects.toThrowError('throw on 2nd');
1298
+ yield sleep(300);
1299
+ expect(loopCount).toBe(2);
1300
+ expect(mappedValues).toEqual([1, 3, 2]);
1301
+ expect(iteratedValues).toEqual([1, 3]);
1302
+ }));
1303
+ it('async mapper works', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1304
+ var _j, e_28, _k, _l;
1305
+ const max = 100;
1306
+ const iterator = new SleepIterator(max);
1307
+ let total = 0;
1308
+ let callCount = 0;
1309
+ const prefetcher = new iterable_mapper_1.IterableMapper(iterator, (value) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1310
+ callCount++;
1311
+ total += value;
1312
+ yield sleep(10 * (callCount % 6));
1313
+ return total;
1314
+ }), { concurrency, maxUnread });
1315
+ let lastTotal = 0;
1316
+ let loopCount = 0;
1317
+ try {
1318
+ for (var _m = true, prefetcher_27 = tslib_1.__asyncValues(prefetcher), prefetcher_27_1; prefetcher_27_1 = yield prefetcher_27.next(), _j = prefetcher_27_1.done, !_j;) {
1319
+ _l = prefetcher_27_1.value;
1320
+ _m = false;
1321
+ try {
1322
+ const item = _l;
1323
+ loopCount++;
1324
+ if (item > lastTotal) {
1325
+ lastTotal = item;
1326
+ }
1327
+ }
1328
+ finally {
1329
+ _m = true;
1330
+ }
1331
+ }
1332
+ }
1333
+ catch (e_28_1) { e_28 = { error: e_28_1 }; }
1334
+ finally {
1335
+ try {
1336
+ if (!_m && !_j && (_k = prefetcher_27.return)) yield _k.call(prefetcher_27);
1337
+ }
1338
+ finally { if (e_28) throw e_28.error; }
1339
+ }
1340
+ expect(callCount).toBe(max);
1341
+ expect(loopCount).toBe(max);
1342
+ expect(total).toBe((max * (max + 1)) / 2);
1343
+ expect(lastTotal).toBe((max * (max + 1)) / 2);
1344
+ }));
1345
+ it('catches exception from mapper - 10 of 10 items - stopOnMapperError true', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1346
+ const input = new SleepIterator(10);
1347
+ const mappedValues = [];
1348
+ const iteratedValues = [];
1349
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => {
1350
+ mappedValues.push(value);
1351
+ throw new Error('throw on each');
1352
+ }, { concurrency, maxUnread, stopOnMapperError: true });
1353
+ let loopCount = 0;
1354
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1355
+ var _o, e_29, _p, _q;
1356
+ try {
1357
+ for (var _r = true, prefetcher_28 = tslib_1.__asyncValues(prefetcher), prefetcher_28_1; prefetcher_28_1 = yield prefetcher_28.next(), _o = prefetcher_28_1.done, !_o;) {
1358
+ _q = prefetcher_28_1.value;
1359
+ _r = false;
1360
+ try {
1361
+ const value = _q;
1362
+ loopCount++;
1363
+ iteratedValues.push(value);
1364
+ }
1365
+ finally {
1366
+ _r = true;
1367
+ }
1368
+ }
1369
+ }
1370
+ catch (e_29_1) { e_29 = { error: e_29_1 }; }
1371
+ finally {
1372
+ try {
1373
+ if (!_r && !_o && (_p = prefetcher_28.return)) yield _p.call(prefetcher_28);
1374
+ }
1375
+ finally { if (e_29) throw e_29.error; }
1376
+ }
1377
+ })).rejects.toThrowError('throw on each');
1378
+ expect(loopCount).toBe(0);
1379
+ expect(mappedValues).toEqual([1]);
1380
+ expect(iteratedValues).toEqual([]);
1381
+ }));
1382
+ it('catches exception from mapper - 10 of 10 items - stopOnMapperError false', () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1383
+ const input = new SleepIterator(10);
1384
+ const mappedValues = [];
1385
+ const iteratedValues = [];
1386
+ const prefetcher = new iterable_mapper_1.IterableMapper(input, (value) => {
1387
+ mappedValues.push(value);
1388
+ throw new Error('throw on each');
1389
+ }, { concurrency, maxUnread, stopOnMapperError: false });
1390
+ let loopCount = 0;
1391
+ yield expect(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
1392
+ var _s, e_30, _t, _u;
1393
+ try {
1394
+ for (var _v = true, prefetcher_29 = tslib_1.__asyncValues(prefetcher), prefetcher_29_1; prefetcher_29_1 = yield prefetcher_29.next(), _s = prefetcher_29_1.done, !_s;) {
1395
+ _u = prefetcher_29_1.value;
1396
+ _v = false;
1397
+ try {
1398
+ const value = _u;
1399
+ loopCount++;
1400
+ iteratedValues.push(value);
1401
+ }
1402
+ finally {
1403
+ _v = true;
1404
+ }
1405
+ }
1406
+ }
1407
+ catch (e_30_1) { e_30 = { error: e_30_1 }; }
1408
+ finally {
1409
+ try {
1410
+ if (!_v && !_s && (_t = prefetcher_29.return)) yield _t.call(prefetcher_29);
1411
+ }
1412
+ finally { if (e_30) throw e_30.error; }
1413
+ }
1414
+ })).rejects.toThrowError('throw on each');
1415
+ expect(loopCount).toBe(0);
1416
+ expect(mappedValues).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
1417
+ expect(iteratedValues).toEqual([]);
1418
+ }));
1419
+ });
1420
+ });
1421
+ //# sourceMappingURL=iterable-mapper.test.js.map