@naturalcycles/js-lib 14.81.0 → 14.82.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/promise/AggregatedError.d.ts +1 -1
- package/dist/promise/AggregatedError.js +2 -7
- package/dist/promise/pFilter.d.ts +2 -3
- package/dist/promise/pFilter.js +4 -4
- package/dist/promise/pMap.d.ts +1 -1
- package/dist/promise/pMap.js +67 -19
- package/dist/promise/pRetry.d.ts +1 -1
- package/dist-esm/index.js +0 -1
- package/dist-esm/promise/AggregatedError.js +2 -7
- package/dist-esm/promise/pFilter.js +4 -4
- package/dist-esm/promise/pMap.js +79 -19
- package/package.json +1 -1
- package/src/index.ts +0 -1
- package/src/promise/AggregatedError.ts +3 -8
- package/src/promise/pFilter.ts +5 -14
- package/src/promise/pMap.ts +72 -21
- package/src/promise/pRetry.ts +1 -1
- package/dist/promise/pBatch.d.ts +0 -7
- package/dist/promise/pBatch.js +0 -30
- package/dist-esm/promise/pBatch.js +0 -23
- package/src/promise/pBatch.ts +0 -31
package/dist/index.d.ts
CHANGED
|
@@ -34,7 +34,6 @@ export * from './object/object.util';
|
|
|
34
34
|
export * from './object/sortObject';
|
|
35
35
|
export * from './object/sortObjectDeep';
|
|
36
36
|
import { AggregatedError } from './promise/AggregatedError';
|
|
37
|
-
export * from './promise/pBatch';
|
|
38
37
|
import { DeferredPromise, pDefer } from './promise/pDefer';
|
|
39
38
|
export * from './promise/pDelay';
|
|
40
39
|
export * from './promise/pFilter';
|
package/dist/index.js
CHANGED
|
@@ -42,7 +42,6 @@ Object.defineProperty(exports, "JsonSchemaAnyBuilder", { enumerable: true, get:
|
|
|
42
42
|
(0, tslib_1.__exportStar)(require("./object/sortObjectDeep"), exports);
|
|
43
43
|
const AggregatedError_1 = require("./promise/AggregatedError");
|
|
44
44
|
Object.defineProperty(exports, "AggregatedError", { enumerable: true, get: function () { return AggregatedError_1.AggregatedError; } });
|
|
45
|
-
(0, tslib_1.__exportStar)(require("./promise/pBatch"), exports);
|
|
46
45
|
const pDefer_1 = require("./promise/pDefer");
|
|
47
46
|
Object.defineProperty(exports, "pDefer", { enumerable: true, get: function () { return pDefer_1.pDefer; } });
|
|
48
47
|
(0, tslib_1.__exportStar)(require("./promise/pDelay"), exports);
|
|
@@ -8,17 +8,12 @@ exports.AggregatedError = void 0;
|
|
|
8
8
|
*/
|
|
9
9
|
class AggregatedError extends Error {
|
|
10
10
|
constructor(errors, results = []) {
|
|
11
|
-
const mappedErrors = errors.map(e => {
|
|
12
|
-
if (typeof e === 'string')
|
|
13
|
-
return new Error(e);
|
|
14
|
-
return e;
|
|
15
|
-
});
|
|
16
11
|
const message = [
|
|
17
12
|
`${errors.length} errors:`,
|
|
18
|
-
...
|
|
13
|
+
...errors.map((e, i) => `${i + 1}. ${e.message}`),
|
|
19
14
|
].join('\n');
|
|
20
15
|
super(message);
|
|
21
|
-
this.errors =
|
|
16
|
+
this.errors = errors;
|
|
22
17
|
this.results = results;
|
|
23
18
|
Object.defineProperty(this, 'name', {
|
|
24
19
|
value: this.constructor.name,
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export declare function pFilter<T>(iterable: Iterable<T | PromiseLike<T>>, filterFn: AbortableAsyncPredicate<T>, opt?: PMapOptions): Promise<T[]>;
|
|
1
|
+
import { AsyncPredicate } from '../types';
|
|
2
|
+
export declare function pFilter<T>(iterable: Iterable<T>, filterFn: AsyncPredicate<T>): Promise<T[]>;
|
package/dist/promise/pFilter.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.pFilter = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
return
|
|
4
|
+
async function pFilter(iterable, filterFn) {
|
|
5
|
+
const items = [...iterable];
|
|
6
|
+
const predicates = await Promise.all(items.map((item, i) => filterFn(item, i)));
|
|
7
|
+
return items.filter((item, i) => predicates[i]);
|
|
8
8
|
}
|
|
9
9
|
exports.pFilter = pFilter;
|
package/dist/promise/pMap.d.ts
CHANGED
|
@@ -41,4 +41,4 @@ export interface PMapOptions {
|
|
|
41
41
|
* //=> ['http://ava.li/', 'http://todomvc.com/']
|
|
42
42
|
* })();
|
|
43
43
|
*/
|
|
44
|
-
export declare function pMap<IN, OUT>(iterable: Iterable<IN
|
|
44
|
+
export declare function pMap<IN, OUT>(iterable: Iterable<IN>, mapper: AbortableAsyncMapper<IN, OUT>, opt?: PMapOptions): Promise<OUT[]>;
|
package/dist/promise/pMap.js
CHANGED
|
@@ -38,28 +38,74 @@ const AggregatedError_1 = require("./AggregatedError");
|
|
|
38
38
|
* })();
|
|
39
39
|
*/
|
|
40
40
|
async function pMap(iterable, mapper, opt = {}) {
|
|
41
|
+
const ret = [];
|
|
42
|
+
// const iterator = iterable[Symbol.iterator]()
|
|
43
|
+
const items = [...iterable];
|
|
44
|
+
const itemsLength = items.length;
|
|
45
|
+
if (itemsLength === 0)
|
|
46
|
+
return []; // short circuit
|
|
47
|
+
const { concurrency = itemsLength, errorMode = __1.ErrorMode.THROW_IMMEDIATELY } = opt;
|
|
48
|
+
const errors = [];
|
|
49
|
+
let isSettled = false;
|
|
50
|
+
let resolvingCount = 0;
|
|
51
|
+
let currentIndex = 0;
|
|
52
|
+
// Special cases that are able to preserve async stack traces
|
|
53
|
+
if (concurrency === 1) {
|
|
54
|
+
// Special case for concurrency == 1
|
|
55
|
+
for await (const item of items) {
|
|
56
|
+
try {
|
|
57
|
+
const r = await mapper(item, currentIndex++);
|
|
58
|
+
if (r === __1.END)
|
|
59
|
+
break;
|
|
60
|
+
if (r !== __1.SKIP)
|
|
61
|
+
ret.push(r);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (errorMode === __1.ErrorMode.THROW_IMMEDIATELY)
|
|
65
|
+
throw err;
|
|
66
|
+
if (errorMode === __1.ErrorMode.THROW_AGGREGATED) {
|
|
67
|
+
errors.push(err);
|
|
68
|
+
}
|
|
69
|
+
// otherwise, suppress completely
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (errors.length) {
|
|
73
|
+
throw new AggregatedError_1.AggregatedError(errors, ret);
|
|
74
|
+
}
|
|
75
|
+
return ret;
|
|
76
|
+
}
|
|
77
|
+
else if (!opt.concurrency || items.length <= opt.concurrency) {
|
|
78
|
+
// Special case for concurrency == infinity or iterable.length < concurrency
|
|
79
|
+
if (errorMode === __1.ErrorMode.THROW_IMMEDIATELY) {
|
|
80
|
+
return (await Promise.all(items.map((item, i) => mapper(item, i)))).filter(r => r !== __1.SKIP && r !== __1.END);
|
|
81
|
+
}
|
|
82
|
+
;
|
|
83
|
+
(await Promise.allSettled(items.map((item, i) => mapper(item, i)))).forEach(r => {
|
|
84
|
+
if (r.status === 'fulfilled') {
|
|
85
|
+
if (r.value !== __1.SKIP && r.value !== __1.END)
|
|
86
|
+
ret.push(r.value);
|
|
87
|
+
}
|
|
88
|
+
else if (errorMode === __1.ErrorMode.THROW_AGGREGATED) {
|
|
89
|
+
errors.push(r.reason);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
if (errors.length) {
|
|
93
|
+
throw new AggregatedError_1.AggregatedError(errors, ret);
|
|
94
|
+
}
|
|
95
|
+
return ret;
|
|
96
|
+
}
|
|
41
97
|
return new Promise((resolve, reject) => {
|
|
42
|
-
const
|
|
43
|
-
const ret = [];
|
|
44
|
-
const iterator = iterable[Symbol.iterator]();
|
|
45
|
-
const errors = [];
|
|
46
|
-
let isSettled = false;
|
|
47
|
-
let isIterableDone = false;
|
|
48
|
-
let resolvingCount = 0;
|
|
49
|
-
let currentIndex = 0;
|
|
50
|
-
const next = (skipped = false) => {
|
|
98
|
+
const next = () => {
|
|
51
99
|
if (isSettled) {
|
|
52
100
|
return;
|
|
53
101
|
}
|
|
54
|
-
const nextItem =
|
|
55
|
-
const i = currentIndex
|
|
56
|
-
if (
|
|
57
|
-
currentIndex++;
|
|
58
|
-
if (nextItem.done) {
|
|
59
|
-
isIterableDone = true;
|
|
102
|
+
const nextItem = items[currentIndex];
|
|
103
|
+
const i = currentIndex++;
|
|
104
|
+
if (currentIndex > itemsLength) {
|
|
60
105
|
if (resolvingCount === 0) {
|
|
106
|
+
isSettled = true;
|
|
61
107
|
const r = ret.filter(r => r !== __1.SKIP);
|
|
62
|
-
if (errors.length
|
|
108
|
+
if (errors.length) {
|
|
63
109
|
reject(new AggregatedError_1.AggregatedError(errors, r));
|
|
64
110
|
}
|
|
65
111
|
else {
|
|
@@ -69,7 +115,7 @@ async function pMap(iterable, mapper, opt = {}) {
|
|
|
69
115
|
return;
|
|
70
116
|
}
|
|
71
117
|
resolvingCount++;
|
|
72
|
-
Promise.resolve(nextItem
|
|
118
|
+
Promise.resolve(nextItem)
|
|
73
119
|
.then(async (element) => await mapper(element, i))
|
|
74
120
|
.then(value => {
|
|
75
121
|
if (value === __1.END) {
|
|
@@ -85,7 +131,9 @@ async function pMap(iterable, mapper, opt = {}) {
|
|
|
85
131
|
reject(err);
|
|
86
132
|
}
|
|
87
133
|
else {
|
|
88
|
-
|
|
134
|
+
if (errorMode === __1.ErrorMode.THROW_AGGREGATED) {
|
|
135
|
+
errors.push(err);
|
|
136
|
+
}
|
|
89
137
|
resolvingCount--;
|
|
90
138
|
next();
|
|
91
139
|
}
|
|
@@ -93,7 +141,7 @@ async function pMap(iterable, mapper, opt = {}) {
|
|
|
93
141
|
};
|
|
94
142
|
for (let i = 0; i < concurrency; i++) {
|
|
95
143
|
next();
|
|
96
|
-
if (
|
|
144
|
+
if (isSettled) {
|
|
97
145
|
break;
|
|
98
146
|
}
|
|
99
147
|
}
|
package/dist/promise/pRetry.d.ts
CHANGED
package/dist-esm/index.js
CHANGED
|
@@ -31,7 +31,6 @@ export * from './object/object.util';
|
|
|
31
31
|
export * from './object/sortObject';
|
|
32
32
|
export * from './object/sortObjectDeep';
|
|
33
33
|
import { AggregatedError } from './promise/AggregatedError';
|
|
34
|
-
export * from './promise/pBatch';
|
|
35
34
|
import { pDefer } from './promise/pDefer';
|
|
36
35
|
export * from './promise/pDelay';
|
|
37
36
|
export * from './promise/pFilter';
|
|
@@ -5,17 +5,12 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export class AggregatedError extends Error {
|
|
7
7
|
constructor(errors, results = []) {
|
|
8
|
-
const mappedErrors = errors.map(e => {
|
|
9
|
-
if (typeof e === 'string')
|
|
10
|
-
return new Error(e);
|
|
11
|
-
return e;
|
|
12
|
-
});
|
|
13
8
|
const message = [
|
|
14
9
|
`${errors.length} errors:`,
|
|
15
|
-
...
|
|
10
|
+
...errors.map((e, i) => `${i + 1}. ${e.message}`),
|
|
16
11
|
].join('\n');
|
|
17
12
|
super(message);
|
|
18
|
-
this.errors =
|
|
13
|
+
this.errors = errors;
|
|
19
14
|
this.results = results;
|
|
20
15
|
Object.defineProperty(this, 'name', {
|
|
21
16
|
value: this.constructor.name,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
return
|
|
1
|
+
export async function pFilter(iterable, filterFn) {
|
|
2
|
+
const items = [...iterable];
|
|
3
|
+
const predicates = await Promise.all(items.map((item, i) => filterFn(item, i)));
|
|
4
|
+
return items.filter((item, i) => predicates[i]);
|
|
5
5
|
}
|
package/dist-esm/promise/pMap.js
CHANGED
|
@@ -6,6 +6,7 @@ Improvements:
|
|
|
6
6
|
- Included Typescript typings (no need for @types/p-map)
|
|
7
7
|
- Compatible with pProps (that had typings issues)
|
|
8
8
|
*/
|
|
9
|
+
import { __asyncValues } from "tslib";
|
|
9
10
|
import { END, ErrorMode, SKIP } from '..';
|
|
10
11
|
import { AggregatedError } from './AggregatedError';
|
|
11
12
|
/**
|
|
@@ -35,28 +36,85 @@ import { AggregatedError } from './AggregatedError';
|
|
|
35
36
|
* })();
|
|
36
37
|
*/
|
|
37
38
|
export async function pMap(iterable, mapper, opt = {}) {
|
|
39
|
+
var e_1, _a;
|
|
40
|
+
const ret = [];
|
|
41
|
+
// const iterator = iterable[Symbol.iterator]()
|
|
42
|
+
const items = [...iterable];
|
|
43
|
+
const itemsLength = items.length;
|
|
44
|
+
if (itemsLength === 0)
|
|
45
|
+
return []; // short circuit
|
|
46
|
+
const { concurrency = itemsLength, errorMode = ErrorMode.THROW_IMMEDIATELY } = opt;
|
|
47
|
+
const errors = [];
|
|
48
|
+
let isSettled = false;
|
|
49
|
+
let resolvingCount = 0;
|
|
50
|
+
let currentIndex = 0;
|
|
51
|
+
// Special cases that are able to preserve async stack traces
|
|
52
|
+
if (concurrency === 1) {
|
|
53
|
+
try {
|
|
54
|
+
// Special case for concurrency == 1
|
|
55
|
+
for (var items_1 = __asyncValues(items), items_1_1; items_1_1 = await items_1.next(), !items_1_1.done;) {
|
|
56
|
+
const item = items_1_1.value;
|
|
57
|
+
try {
|
|
58
|
+
const r = await mapper(item, currentIndex++);
|
|
59
|
+
if (r === END)
|
|
60
|
+
break;
|
|
61
|
+
if (r !== SKIP)
|
|
62
|
+
ret.push(r);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
if (errorMode === ErrorMode.THROW_IMMEDIATELY)
|
|
66
|
+
throw err;
|
|
67
|
+
if (errorMode === ErrorMode.THROW_AGGREGATED) {
|
|
68
|
+
errors.push(err);
|
|
69
|
+
}
|
|
70
|
+
// otherwise, suppress completely
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
75
|
+
finally {
|
|
76
|
+
try {
|
|
77
|
+
if (items_1_1 && !items_1_1.done && (_a = items_1.return)) await _a.call(items_1);
|
|
78
|
+
}
|
|
79
|
+
finally { if (e_1) throw e_1.error; }
|
|
80
|
+
}
|
|
81
|
+
if (errors.length) {
|
|
82
|
+
throw new AggregatedError(errors, ret);
|
|
83
|
+
}
|
|
84
|
+
return ret;
|
|
85
|
+
}
|
|
86
|
+
else if (!opt.concurrency || items.length <= opt.concurrency) {
|
|
87
|
+
// Special case for concurrency == infinity or iterable.length < concurrency
|
|
88
|
+
if (errorMode === ErrorMode.THROW_IMMEDIATELY) {
|
|
89
|
+
return (await Promise.all(items.map((item, i) => mapper(item, i)))).filter(r => r !== SKIP && r !== END);
|
|
90
|
+
}
|
|
91
|
+
;
|
|
92
|
+
(await Promise.allSettled(items.map((item, i) => mapper(item, i)))).forEach(r => {
|
|
93
|
+
if (r.status === 'fulfilled') {
|
|
94
|
+
if (r.value !== SKIP && r.value !== END)
|
|
95
|
+
ret.push(r.value);
|
|
96
|
+
}
|
|
97
|
+
else if (errorMode === ErrorMode.THROW_AGGREGATED) {
|
|
98
|
+
errors.push(r.reason);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
if (errors.length) {
|
|
102
|
+
throw new AggregatedError(errors, ret);
|
|
103
|
+
}
|
|
104
|
+
return ret;
|
|
105
|
+
}
|
|
38
106
|
return new Promise((resolve, reject) => {
|
|
39
|
-
const
|
|
40
|
-
const ret = [];
|
|
41
|
-
const iterator = iterable[Symbol.iterator]();
|
|
42
|
-
const errors = [];
|
|
43
|
-
let isSettled = false;
|
|
44
|
-
let isIterableDone = false;
|
|
45
|
-
let resolvingCount = 0;
|
|
46
|
-
let currentIndex = 0;
|
|
47
|
-
const next = (skipped = false) => {
|
|
107
|
+
const next = () => {
|
|
48
108
|
if (isSettled) {
|
|
49
109
|
return;
|
|
50
110
|
}
|
|
51
|
-
const nextItem =
|
|
52
|
-
const i = currentIndex
|
|
53
|
-
if (
|
|
54
|
-
currentIndex++;
|
|
55
|
-
if (nextItem.done) {
|
|
56
|
-
isIterableDone = true;
|
|
111
|
+
const nextItem = items[currentIndex];
|
|
112
|
+
const i = currentIndex++;
|
|
113
|
+
if (currentIndex > itemsLength) {
|
|
57
114
|
if (resolvingCount === 0) {
|
|
115
|
+
isSettled = true;
|
|
58
116
|
const r = ret.filter(r => r !== SKIP);
|
|
59
|
-
if (errors.length
|
|
117
|
+
if (errors.length) {
|
|
60
118
|
reject(new AggregatedError(errors, r));
|
|
61
119
|
}
|
|
62
120
|
else {
|
|
@@ -66,7 +124,7 @@ export async function pMap(iterable, mapper, opt = {}) {
|
|
|
66
124
|
return;
|
|
67
125
|
}
|
|
68
126
|
resolvingCount++;
|
|
69
|
-
Promise.resolve(nextItem
|
|
127
|
+
Promise.resolve(nextItem)
|
|
70
128
|
.then(async (element) => await mapper(element, i))
|
|
71
129
|
.then(value => {
|
|
72
130
|
if (value === END) {
|
|
@@ -82,7 +140,9 @@ export async function pMap(iterable, mapper, opt = {}) {
|
|
|
82
140
|
reject(err);
|
|
83
141
|
}
|
|
84
142
|
else {
|
|
85
|
-
|
|
143
|
+
if (errorMode === ErrorMode.THROW_AGGREGATED) {
|
|
144
|
+
errors.push(err);
|
|
145
|
+
}
|
|
86
146
|
resolvingCount--;
|
|
87
147
|
next();
|
|
88
148
|
}
|
|
@@ -90,7 +150,7 @@ export async function pMap(iterable, mapper, opt = {}) {
|
|
|
90
150
|
};
|
|
91
151
|
for (let i = 0; i < concurrency; i++) {
|
|
92
152
|
next();
|
|
93
|
-
if (
|
|
153
|
+
if (isSettled) {
|
|
94
154
|
break;
|
|
95
155
|
}
|
|
96
156
|
}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -67,7 +67,6 @@ export * from './object/object.util'
|
|
|
67
67
|
export * from './object/sortObject'
|
|
68
68
|
export * from './object/sortObjectDeep'
|
|
69
69
|
import { AggregatedError } from './promise/AggregatedError'
|
|
70
|
-
export * from './promise/pBatch'
|
|
71
70
|
import { DeferredPromise, pDefer } from './promise/pDefer'
|
|
72
71
|
export * from './promise/pDelay'
|
|
73
72
|
export * from './promise/pFilter'
|
|
@@ -7,20 +7,15 @@ export class AggregatedError<RESULT = any> extends Error {
|
|
|
7
7
|
errors!: Error[]
|
|
8
8
|
results!: RESULT[]
|
|
9
9
|
|
|
10
|
-
constructor(errors:
|
|
11
|
-
const mappedErrors = errors.map(e => {
|
|
12
|
-
if (typeof e === 'string') return new Error(e)
|
|
13
|
-
return e
|
|
14
|
-
})
|
|
15
|
-
|
|
10
|
+
constructor(errors: Error[], results: RESULT[] = []) {
|
|
16
11
|
const message = [
|
|
17
12
|
`${errors.length} errors:`,
|
|
18
|
-
...
|
|
13
|
+
...errors.map((e, i) => `${i + 1}. ${e.message}`),
|
|
19
14
|
].join('\n')
|
|
20
15
|
|
|
21
16
|
super(message)
|
|
22
17
|
|
|
23
|
-
this.errors =
|
|
18
|
+
this.errors = errors
|
|
24
19
|
this.results = results
|
|
25
20
|
|
|
26
21
|
Object.defineProperty(this, 'name', {
|
package/src/promise/pFilter.ts
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { pMap, PMapOptions } from './pMap'
|
|
1
|
+
import { AsyncPredicate } from '../types'
|
|
3
2
|
|
|
4
|
-
export async function pFilter<T>(
|
|
5
|
-
|
|
6
|
-
filterFn
|
|
7
|
-
|
|
8
|
-
): Promise<T[]> {
|
|
9
|
-
const values = await pMap(
|
|
10
|
-
iterable,
|
|
11
|
-
async (item, index) => await Promise.all([filterFn(item, index), item]),
|
|
12
|
-
opt,
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
return values.filter(value => Boolean(value[0])).map(value => value[1])
|
|
3
|
+
export async function pFilter<T>(iterable: Iterable<T>, filterFn: AsyncPredicate<T>): Promise<T[]> {
|
|
4
|
+
const items = [...iterable]
|
|
5
|
+
const predicates = await Promise.all(items.map((item, i) => filterFn(item, i)))
|
|
6
|
+
return items.filter((item, i) => predicates[i])
|
|
16
7
|
}
|
package/src/promise/pMap.ts
CHANGED
|
@@ -55,36 +55,85 @@ export interface PMapOptions {
|
|
|
55
55
|
* })();
|
|
56
56
|
*/
|
|
57
57
|
export async function pMap<IN, OUT>(
|
|
58
|
-
iterable: Iterable<IN
|
|
58
|
+
iterable: Iterable<IN>,
|
|
59
59
|
mapper: AbortableAsyncMapper<IN, OUT>,
|
|
60
60
|
opt: PMapOptions = {},
|
|
61
61
|
): Promise<OUT[]> {
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
const ret: (OUT | typeof SKIP)[] = []
|
|
63
|
+
// const iterator = iterable[Symbol.iterator]()
|
|
64
|
+
const items = [...iterable]
|
|
65
|
+
const itemsLength = items.length
|
|
66
|
+
if (itemsLength === 0) return [] // short circuit
|
|
67
|
+
|
|
68
|
+
const { concurrency = itemsLength, errorMode = ErrorMode.THROW_IMMEDIATELY } = opt
|
|
69
|
+
|
|
70
|
+
const errors: Error[] = []
|
|
71
|
+
let isSettled = false
|
|
72
|
+
let resolvingCount = 0
|
|
73
|
+
let currentIndex = 0
|
|
74
|
+
|
|
75
|
+
// Special cases that are able to preserve async stack traces
|
|
76
|
+
|
|
77
|
+
if (concurrency === 1) {
|
|
78
|
+
// Special case for concurrency == 1
|
|
79
|
+
|
|
80
|
+
for await (const item of items) {
|
|
81
|
+
try {
|
|
82
|
+
const r = await mapper(item, currentIndex++)
|
|
83
|
+
if (r === END) break
|
|
84
|
+
if (r !== SKIP) ret.push(r)
|
|
85
|
+
} catch (err) {
|
|
86
|
+
if (errorMode === ErrorMode.THROW_IMMEDIATELY) throw err
|
|
87
|
+
if (errorMode === ErrorMode.THROW_AGGREGATED) {
|
|
88
|
+
errors.push(err as Error)
|
|
89
|
+
}
|
|
90
|
+
// otherwise, suppress completely
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (errors.length) {
|
|
95
|
+
throw new AggregatedError(errors, ret)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return ret as OUT[]
|
|
99
|
+
} else if (!opt.concurrency || items.length <= opt.concurrency) {
|
|
100
|
+
// Special case for concurrency == infinity or iterable.length < concurrency
|
|
101
|
+
|
|
102
|
+
if (errorMode === ErrorMode.THROW_IMMEDIATELY) {
|
|
103
|
+
return (await Promise.all(items.map((item, i) => mapper(item, i)))).filter(
|
|
104
|
+
r => r !== SKIP && r !== END,
|
|
105
|
+
) as OUT[]
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
;(await Promise.allSettled(items.map((item, i) => mapper(item, i)))).forEach(r => {
|
|
109
|
+
if (r.status === 'fulfilled') {
|
|
110
|
+
if (r.value !== SKIP && r.value !== END) ret.push(r.value)
|
|
111
|
+
} else if (errorMode === ErrorMode.THROW_AGGREGATED) {
|
|
112
|
+
errors.push(r.reason)
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
if (errors.length) {
|
|
117
|
+
throw new AggregatedError(errors, ret)
|
|
118
|
+
}
|
|
64
119
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const errors: Error[] = []
|
|
68
|
-
let isSettled = false
|
|
69
|
-
let isIterableDone = false
|
|
70
|
-
let resolvingCount = 0
|
|
71
|
-
let currentIndex = 0
|
|
120
|
+
return ret as OUT[]
|
|
121
|
+
}
|
|
72
122
|
|
|
73
|
-
|
|
123
|
+
return new Promise<OUT[]>((resolve, reject) => {
|
|
124
|
+
const next = () => {
|
|
74
125
|
if (isSettled) {
|
|
75
126
|
return
|
|
76
127
|
}
|
|
77
128
|
|
|
78
|
-
const nextItem =
|
|
79
|
-
const i = currentIndex
|
|
80
|
-
if (!skipped) currentIndex++
|
|
81
|
-
|
|
82
|
-
if (nextItem.done) {
|
|
83
|
-
isIterableDone = true
|
|
129
|
+
const nextItem = items[currentIndex]!
|
|
130
|
+
const i = currentIndex++
|
|
84
131
|
|
|
132
|
+
if (currentIndex > itemsLength) {
|
|
85
133
|
if (resolvingCount === 0) {
|
|
134
|
+
isSettled = true
|
|
86
135
|
const r = ret.filter(r => r !== SKIP) as OUT[]
|
|
87
|
-
if (errors.length
|
|
136
|
+
if (errors.length) {
|
|
88
137
|
reject(new AggregatedError(errors, r))
|
|
89
138
|
} else {
|
|
90
139
|
resolve(r)
|
|
@@ -96,7 +145,7 @@ export async function pMap<IN, OUT>(
|
|
|
96
145
|
|
|
97
146
|
resolvingCount++
|
|
98
147
|
|
|
99
|
-
Promise.resolve(nextItem
|
|
148
|
+
Promise.resolve(nextItem)
|
|
100
149
|
.then(async element => await mapper(element, i))
|
|
101
150
|
.then(
|
|
102
151
|
value => {
|
|
@@ -114,7 +163,9 @@ export async function pMap<IN, OUT>(
|
|
|
114
163
|
isSettled = true
|
|
115
164
|
reject(err)
|
|
116
165
|
} else {
|
|
117
|
-
|
|
166
|
+
if (errorMode === ErrorMode.THROW_AGGREGATED) {
|
|
167
|
+
errors.push(err)
|
|
168
|
+
}
|
|
118
169
|
resolvingCount--
|
|
119
170
|
next()
|
|
120
171
|
}
|
|
@@ -125,7 +176,7 @@ export async function pMap<IN, OUT>(
|
|
|
125
176
|
for (let i = 0; i < concurrency; i++) {
|
|
126
177
|
next()
|
|
127
178
|
|
|
128
|
-
if (
|
|
179
|
+
if (isSettled) {
|
|
129
180
|
break
|
|
130
181
|
}
|
|
131
182
|
}
|
package/src/promise/pRetry.ts
CHANGED
package/dist/promise/pBatch.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { AbortableAsyncMapper, BatchResult } from '..';
|
|
2
|
-
/**
|
|
3
|
-
* Like pMap, but doesn't fail on errors, instead returns both successful results and errors.
|
|
4
|
-
*/
|
|
5
|
-
export declare function pBatch<IN, OUT>(iterable: Iterable<IN | PromiseLike<IN>>, mapper: AbortableAsyncMapper<IN, OUT>, opt?: {
|
|
6
|
-
concurrency?: number;
|
|
7
|
-
}): Promise<BatchResult<OUT>>;
|
package/dist/promise/pBatch.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.pBatch = void 0;
|
|
4
|
-
const __1 = require("..");
|
|
5
|
-
const pMap_1 = require("./pMap");
|
|
6
|
-
/**
|
|
7
|
-
* Like pMap, but doesn't fail on errors, instead returns both successful results and errors.
|
|
8
|
-
*/
|
|
9
|
-
async function pBatch(iterable, mapper, opt) {
|
|
10
|
-
try {
|
|
11
|
-
const results = await (0, pMap_1.pMap)(iterable, mapper, {
|
|
12
|
-
...opt,
|
|
13
|
-
errorMode: __1.ErrorMode.THROW_AGGREGATED,
|
|
14
|
-
});
|
|
15
|
-
return {
|
|
16
|
-
results,
|
|
17
|
-
errors: [],
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
catch (err) {
|
|
21
|
-
const { errors, results } = err;
|
|
22
|
-
if (!errors || !results)
|
|
23
|
-
throw err; // not an AggregatedError
|
|
24
|
-
return {
|
|
25
|
-
results,
|
|
26
|
-
errors,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
exports.pBatch = pBatch;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { ErrorMode } from '..';
|
|
2
|
-
import { pMap } from './pMap';
|
|
3
|
-
/**
|
|
4
|
-
* Like pMap, but doesn't fail on errors, instead returns both successful results and errors.
|
|
5
|
-
*/
|
|
6
|
-
export async function pBatch(iterable, mapper, opt) {
|
|
7
|
-
try {
|
|
8
|
-
const results = await pMap(iterable, mapper, Object.assign(Object.assign({}, opt), { errorMode: ErrorMode.THROW_AGGREGATED }));
|
|
9
|
-
return {
|
|
10
|
-
results,
|
|
11
|
-
errors: [],
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
catch (err) {
|
|
15
|
-
const { errors, results } = err;
|
|
16
|
-
if (!errors || !results)
|
|
17
|
-
throw err; // not an AggregatedError
|
|
18
|
-
return {
|
|
19
|
-
results,
|
|
20
|
-
errors,
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
}
|
package/src/promise/pBatch.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { AbortableAsyncMapper, BatchResult, ErrorMode } from '..'
|
|
2
|
-
import { AggregatedError } from './AggregatedError'
|
|
3
|
-
import { pMap } from './pMap'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Like pMap, but doesn't fail on errors, instead returns both successful results and errors.
|
|
7
|
-
*/
|
|
8
|
-
export async function pBatch<IN, OUT>(
|
|
9
|
-
iterable: Iterable<IN | PromiseLike<IN>>,
|
|
10
|
-
mapper: AbortableAsyncMapper<IN, OUT>,
|
|
11
|
-
opt?: { concurrency?: number },
|
|
12
|
-
): Promise<BatchResult<OUT>> {
|
|
13
|
-
try {
|
|
14
|
-
const results = await pMap(iterable, mapper, {
|
|
15
|
-
...opt,
|
|
16
|
-
errorMode: ErrorMode.THROW_AGGREGATED,
|
|
17
|
-
})
|
|
18
|
-
return {
|
|
19
|
-
results,
|
|
20
|
-
errors: [],
|
|
21
|
-
}
|
|
22
|
-
} catch (err) {
|
|
23
|
-
const { errors, results } = err as AggregatedError<OUT>
|
|
24
|
-
if (!errors || !results) throw err // not an AggregatedError
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
results,
|
|
28
|
-
errors,
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|