@naturalcycles/js-lib
Advanced tools
Comparing version 14.218.0 to 14.219.0
@@ -1,11 +0,11 @@ | ||
/* | ||
Taken from https://github.com/sindresorhus/p-map | ||
Improvements: | ||
- Exported as { pMap }, so IDE auto-completion works | ||
- Included Typescript typings (no need for @types/p-map) | ||
- Compatible with pProps (that had typings issues) | ||
*/ | ||
import { END, ErrorMode, SKIP } from '..'; | ||
/** | ||
* Forked from https://github.com/sindresorhus/p-map | ||
* | ||
* Improvements: | ||
* - Exported as { pMap }, so IDE auto-completion works | ||
* - Included Typescript typings (no need for @types/p-map) | ||
* - Compatible with pProps (that had typings issues) | ||
* - Preserves async stack traces (in selected cases) | ||
* | ||
* Returns a `Promise` that is fulfilled when all promises in `input` and ones returned from `mapper` are fulfilled, | ||
@@ -37,5 +37,2 @@ * or rejects if any of the promises reject. The fulfilled value is an `Array` of the fulfilled values returned | ||
export async function pMap(iterable, mapper, opt = {}) { | ||
const { logger = console } = opt; | ||
const ret = []; | ||
// const iterator = iterable[Symbol.iterator]() | ||
const items = [...iterable]; | ||
@@ -45,3 +42,14 @@ const itemsLength = items.length; | ||
return []; // short circuit | ||
const { concurrency = itemsLength, errorMode = ErrorMode.THROW_IMMEDIATELY } = opt; | ||
const { concurrency = 16, errorMode = ErrorMode.THROW_IMMEDIATELY, logger = console } = opt; | ||
// Special cases that are able to preserve async stack traces | ||
// Special case: serial execution | ||
if (concurrency === 1) { | ||
return await pMap1(items, mapper, errorMode, logger); | ||
} | ||
// Special case: concurrency === Infinity or items.length <= concurrency | ||
if (concurrency === Infinity || items.length <= concurrency) { | ||
return await pMapAll(items, mapper, errorMode, logger); | ||
} | ||
// General case: execution with throttled concurrency | ||
const ret = []; | ||
const errors = []; | ||
@@ -51,54 +59,2 @@ let isSettled = false; | ||
let currentIndex = 0; | ||
// Special cases that are able to preserve async stack traces | ||
if (concurrency === 1) { | ||
// Special case for concurrency == 1 | ||
for (const item of items) { | ||
try { | ||
const r = await mapper(item, currentIndex++); | ||
if (r === END) | ||
break; | ||
if (r !== SKIP) | ||
ret.push(r); | ||
} | ||
catch (err) { | ||
if (errorMode === ErrorMode.THROW_IMMEDIATELY) | ||
throw err; | ||
if (errorMode === ErrorMode.THROW_AGGREGATED) { | ||
errors.push(err); | ||
} | ||
else { | ||
// otherwise, suppress (but still log via logger) | ||
logger === null || logger === void 0 ? void 0 : logger.error(err); | ||
} | ||
} | ||
} | ||
if (errors.length) { | ||
throw new AggregateError(errors, `pMap resulted in ${errors.length} error(s)`); | ||
} | ||
return ret; | ||
} | ||
else if (!opt.concurrency || items.length <= opt.concurrency) { | ||
// Special case for concurrency == infinity or iterable.length < concurrency | ||
if (errorMode === ErrorMode.THROW_IMMEDIATELY) { | ||
return (await Promise.all(items.map((item, i) => mapper(item, i)))).filter(r => r !== SKIP && r !== END); | ||
} | ||
; | ||
(await Promise.allSettled(items.map((item, i) => mapper(item, i)))).forEach(r => { | ||
if (r.status === 'fulfilled') { | ||
if (r.value !== SKIP && r.value !== END) | ||
ret.push(r.value); | ||
} | ||
else if (errorMode === ErrorMode.THROW_AGGREGATED) { | ||
errors.push(r.reason); | ||
} | ||
else { | ||
// otherwise, suppress (but still log via logger) | ||
logger === null || logger === void 0 ? void 0 : logger.error(r.reason); | ||
} | ||
}); | ||
if (errors.length) { | ||
throw new AggregateError(errors, `pMap resulted in ${errors.length} error(s)`); | ||
} | ||
return ret; | ||
} | ||
return await new Promise((resolve, reject) => { | ||
@@ -161,1 +117,62 @@ const next = () => { | ||
} | ||
/** | ||
pMap with serial (non-concurrent) execution. | ||
*/ | ||
async function pMap1(items, mapper, errorMode, logger) { | ||
let i = 0; | ||
const ret = []; | ||
const errors = []; | ||
for (const item of items) { | ||
try { | ||
const r = await mapper(item, i++); | ||
if (r === END) | ||
break; | ||
if (r !== SKIP) | ||
ret.push(r); | ||
} | ||
catch (err) { | ||
if (errorMode === ErrorMode.THROW_IMMEDIATELY) | ||
throw err; | ||
if (errorMode === ErrorMode.THROW_AGGREGATED) { | ||
errors.push(err); | ||
} | ||
else { | ||
// otherwise, suppress (but still log via logger) | ||
logger === null || logger === void 0 ? void 0 : logger.error(err); | ||
} | ||
} | ||
} | ||
if (errors.length) { | ||
throw new AggregateError(errors, `pMap resulted in ${errors.length} error(s)`); | ||
} | ||
return ret; | ||
} | ||
/** | ||
pMap with fully concurrent execution, like Promise.all | ||
*/ | ||
async function pMapAll(items, mapper, errorMode, logger) { | ||
if (errorMode === ErrorMode.THROW_IMMEDIATELY) { | ||
return (await Promise.all(items.map((item, i) => mapper(item, i)))).filter(r => r !== SKIP && r !== END); | ||
} | ||
const ret = []; | ||
const errors = []; | ||
for (const r of await Promise.allSettled(items.map((item, i) => mapper(item, i)))) { | ||
if (r.status === 'fulfilled') { | ||
if (r.value === END) | ||
break; | ||
if (r.value !== SKIP) | ||
ret.push(r.value); | ||
} | ||
else if (errorMode === ErrorMode.THROW_AGGREGATED) { | ||
errors.push(r.reason); | ||
} | ||
else { | ||
// otherwise, suppress (but still log via logger) | ||
logger === null || logger === void 0 ? void 0 : logger.error(r.reason); | ||
} | ||
} | ||
if (errors.length) { | ||
throw new AggregateError(errors, `pMap resulted in ${errors.length} error(s)`); | ||
} | ||
return ret; | ||
} |
@@ -7,3 +7,7 @@ import type { AbortableAsyncMapper, CommonLogger } from '..'; | ||
* | ||
* @default Infinity | ||
* Defaults to 16. | ||
* | ||
* It previously (and originally) defaulted to Infinity, which was later changed, | ||
* because it's somewhat dangerous to run "infinite number of parallel promises". | ||
* You can still emulate the old behavior by passing `Infinity`. | ||
*/ | ||
@@ -27,2 +31,10 @@ concurrency?: number; | ||
/** | ||
* Forked from https://github.com/sindresorhus/p-map | ||
* | ||
* Improvements: | ||
* - Exported as { pMap }, so IDE auto-completion works | ||
* - Included Typescript typings (no need for @types/p-map) | ||
* - Compatible with pProps (that had typings issues) | ||
* - Preserves async stack traces (in selected cases) | ||
* | ||
* Returns a `Promise` that is fulfilled when all promises in `input` and ones returned from `mapper` are fulfilled, | ||
@@ -29,0 +41,0 @@ * or rejects if any of the promises reject. The fulfilled value is an `Array` of the fulfilled values returned |
"use strict"; | ||
/* | ||
Taken from https://github.com/sindresorhus/p-map | ||
Improvements: | ||
- Exported as { pMap }, so IDE auto-completion works | ||
- Included Typescript typings (no need for @types/p-map) | ||
- Compatible with pProps (that had typings issues) | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -14,2 +6,10 @@ exports.pMap = void 0; | ||
/** | ||
* Forked from https://github.com/sindresorhus/p-map | ||
* | ||
* Improvements: | ||
* - Exported as { pMap }, so IDE auto-completion works | ||
* - Included Typescript typings (no need for @types/p-map) | ||
* - Compatible with pProps (that had typings issues) | ||
* - Preserves async stack traces (in selected cases) | ||
* | ||
* Returns a `Promise` that is fulfilled when all promises in `input` and ones returned from `mapper` are fulfilled, | ||
@@ -41,5 +41,2 @@ * or rejects if any of the promises reject. The fulfilled value is an `Array` of the fulfilled values returned | ||
async function pMap(iterable, mapper, opt = {}) { | ||
const { logger = console } = opt; | ||
const ret = []; | ||
// const iterator = iterable[Symbol.iterator]() | ||
const items = [...iterable]; | ||
@@ -49,3 +46,14 @@ const itemsLength = items.length; | ||
return []; // short circuit | ||
const { concurrency = itemsLength, errorMode = __1.ErrorMode.THROW_IMMEDIATELY } = opt; | ||
const { concurrency = 16, errorMode = __1.ErrorMode.THROW_IMMEDIATELY, logger = console } = opt; | ||
// Special cases that are able to preserve async stack traces | ||
// Special case: serial execution | ||
if (concurrency === 1) { | ||
return await pMap1(items, mapper, errorMode, logger); | ||
} | ||
// Special case: concurrency === Infinity or items.length <= concurrency | ||
if (concurrency === Infinity || items.length <= concurrency) { | ||
return await pMapAll(items, mapper, errorMode, logger); | ||
} | ||
// General case: execution with throttled concurrency | ||
const ret = []; | ||
const errors = []; | ||
@@ -55,54 +63,2 @@ let isSettled = false; | ||
let currentIndex = 0; | ||
// Special cases that are able to preserve async stack traces | ||
if (concurrency === 1) { | ||
// Special case for concurrency == 1 | ||
for (const item of items) { | ||
try { | ||
const r = await mapper(item, currentIndex++); | ||
if (r === __1.END) | ||
break; | ||
if (r !== __1.SKIP) | ||
ret.push(r); | ||
} | ||
catch (err) { | ||
if (errorMode === __1.ErrorMode.THROW_IMMEDIATELY) | ||
throw err; | ||
if (errorMode === __1.ErrorMode.THROW_AGGREGATED) { | ||
errors.push(err); | ||
} | ||
else { | ||
// otherwise, suppress (but still log via logger) | ||
logger?.error(err); | ||
} | ||
} | ||
} | ||
if (errors.length) { | ||
throw new AggregateError(errors, `pMap resulted in ${errors.length} error(s)`); | ||
} | ||
return ret; | ||
} | ||
else if (!opt.concurrency || items.length <= opt.concurrency) { | ||
// Special case for concurrency == infinity or iterable.length < concurrency | ||
if (errorMode === __1.ErrorMode.THROW_IMMEDIATELY) { | ||
return (await Promise.all(items.map((item, i) => mapper(item, i)))).filter(r => r !== __1.SKIP && r !== __1.END); | ||
} | ||
; | ||
(await Promise.allSettled(items.map((item, i) => mapper(item, i)))).forEach(r => { | ||
if (r.status === 'fulfilled') { | ||
if (r.value !== __1.SKIP && r.value !== __1.END) | ||
ret.push(r.value); | ||
} | ||
else if (errorMode === __1.ErrorMode.THROW_AGGREGATED) { | ||
errors.push(r.reason); | ||
} | ||
else { | ||
// otherwise, suppress (but still log via logger) | ||
logger?.error(r.reason); | ||
} | ||
}); | ||
if (errors.length) { | ||
throw new AggregateError(errors, `pMap resulted in ${errors.length} error(s)`); | ||
} | ||
return ret; | ||
} | ||
return await new Promise((resolve, reject) => { | ||
@@ -166,1 +122,62 @@ const next = () => { | ||
exports.pMap = pMap; | ||
/** | ||
pMap with serial (non-concurrent) execution. | ||
*/ | ||
async function pMap1(items, mapper, errorMode, logger) { | ||
let i = 0; | ||
const ret = []; | ||
const errors = []; | ||
for (const item of items) { | ||
try { | ||
const r = await mapper(item, i++); | ||
if (r === __1.END) | ||
break; | ||
if (r !== __1.SKIP) | ||
ret.push(r); | ||
} | ||
catch (err) { | ||
if (errorMode === __1.ErrorMode.THROW_IMMEDIATELY) | ||
throw err; | ||
if (errorMode === __1.ErrorMode.THROW_AGGREGATED) { | ||
errors.push(err); | ||
} | ||
else { | ||
// otherwise, suppress (but still log via logger) | ||
logger?.error(err); | ||
} | ||
} | ||
} | ||
if (errors.length) { | ||
throw new AggregateError(errors, `pMap resulted in ${errors.length} error(s)`); | ||
} | ||
return ret; | ||
} | ||
/** | ||
pMap with fully concurrent execution, like Promise.all | ||
*/ | ||
async function pMapAll(items, mapper, errorMode, logger) { | ||
if (errorMode === __1.ErrorMode.THROW_IMMEDIATELY) { | ||
return (await Promise.all(items.map((item, i) => mapper(item, i)))).filter(r => r !== __1.SKIP && r !== __1.END); | ||
} | ||
const ret = []; | ||
const errors = []; | ||
for (const r of await Promise.allSettled(items.map((item, i) => mapper(item, i)))) { | ||
if (r.status === 'fulfilled') { | ||
if (r.value === __1.END) | ||
break; | ||
if (r.value !== __1.SKIP) | ||
ret.push(r.value); | ||
} | ||
else if (errorMode === __1.ErrorMode.THROW_AGGREGATED) { | ||
errors.push(r.reason); | ||
} | ||
else { | ||
// otherwise, suppress (but still log via logger) | ||
logger?.error(r.reason); | ||
} | ||
} | ||
if (errors.length) { | ||
throw new AggregateError(errors, `pMap resulted in ${errors.length} error(s)`); | ||
} | ||
return ret; | ||
} |
{ | ||
"name": "@naturalcycles/js-lib", | ||
"version": "14.218.0", | ||
"version": "14.219.0", | ||
"scripts": { | ||
@@ -5,0 +5,0 @@ "prepare": "husky", |
@@ -1,10 +0,1 @@ | ||
/* | ||
Taken from https://github.com/sindresorhus/p-map | ||
Improvements: | ||
- Exported as { pMap }, so IDE auto-completion works | ||
- Included Typescript typings (no need for @types/p-map) | ||
- Compatible with pProps (that had typings issues) | ||
*/ | ||
import type { AbortableAsyncMapper, CommonLogger } from '..' | ||
@@ -17,3 +8,7 @@ import { END, ErrorMode, SKIP } from '..' | ||
* | ||
* @default Infinity | ||
* Defaults to 16. | ||
* | ||
* It previously (and originally) defaulted to Infinity, which was later changed, | ||
* because it's somewhat dangerous to run "infinite number of parallel promises". | ||
* You can still emulate the old behavior by passing `Infinity`. | ||
*/ | ||
@@ -40,2 +35,10 @@ concurrency?: number | ||
/** | ||
* Forked from https://github.com/sindresorhus/p-map | ||
* | ||
* Improvements: | ||
* - Exported as { pMap }, so IDE auto-completion works | ||
* - Included Typescript typings (no need for @types/p-map) | ||
* - Compatible with pProps (that had typings issues) | ||
* - Preserves async stack traces (in selected cases) | ||
* | ||
* Returns a `Promise` that is fulfilled when all promises in `input` and ones returned from `mapper` are fulfilled, | ||
@@ -71,5 +74,2 @@ * or rejects if any of the promises reject. The fulfilled value is an `Array` of the fulfilled values returned | ||
): Promise<OUT[]> { | ||
const { logger = console } = opt | ||
const ret: (OUT | typeof SKIP)[] = [] | ||
// const iterator = iterable[Symbol.iterator]() | ||
const items = [...iterable] | ||
@@ -79,4 +79,17 @@ const itemsLength = items.length | ||
const { concurrency = itemsLength, errorMode = ErrorMode.THROW_IMMEDIATELY } = opt | ||
const { concurrency = 16, errorMode = ErrorMode.THROW_IMMEDIATELY, logger = console } = opt | ||
// Special cases that are able to preserve async stack traces | ||
// Special case: serial execution | ||
if (concurrency === 1) { | ||
return await pMap1(items, mapper, errorMode, logger) | ||
} | ||
// Special case: concurrency === Infinity or items.length <= concurrency | ||
if (concurrency === Infinity || items.length <= concurrency) { | ||
return await pMapAll(items, mapper, errorMode, logger) | ||
} | ||
// General case: execution with throttled concurrency | ||
const ret: (OUT | typeof SKIP)[] = [] | ||
const errors: Error[] = [] | ||
@@ -87,55 +100,2 @@ let isSettled = false | ||
// Special cases that are able to preserve async stack traces | ||
if (concurrency === 1) { | ||
// Special case for concurrency == 1 | ||
for (const item of items) { | ||
try { | ||
const r = await mapper(item, currentIndex++) | ||
if (r === END) break | ||
if (r !== SKIP) ret.push(r) | ||
} catch (err) { | ||
if (errorMode === ErrorMode.THROW_IMMEDIATELY) throw err | ||
if (errorMode === ErrorMode.THROW_AGGREGATED) { | ||
errors.push(err as Error) | ||
} else { | ||
// otherwise, suppress (but still log via logger) | ||
logger?.error(err) | ||
} | ||
} | ||
} | ||
if (errors.length) { | ||
throw new AggregateError(errors, `pMap resulted in ${errors.length} error(s)`) | ||
} | ||
return ret as OUT[] | ||
} else if (!opt.concurrency || items.length <= opt.concurrency) { | ||
// Special case for concurrency == infinity or iterable.length < concurrency | ||
if (errorMode === ErrorMode.THROW_IMMEDIATELY) { | ||
return (await Promise.all(items.map((item, i) => mapper(item, i)))).filter( | ||
r => r !== SKIP && r !== END, | ||
) as OUT[] | ||
} | ||
;(await Promise.allSettled(items.map((item, i) => mapper(item, i)))).forEach(r => { | ||
if (r.status === 'fulfilled') { | ||
if (r.value !== SKIP && r.value !== END) ret.push(r.value) | ||
} else if (errorMode === ErrorMode.THROW_AGGREGATED) { | ||
errors.push(r.reason) | ||
} else { | ||
// otherwise, suppress (but still log via logger) | ||
logger?.error(r.reason) | ||
} | ||
}) | ||
if (errors.length) { | ||
throw new AggregateError(errors, `pMap resulted in ${errors.length} error(s)`) | ||
} | ||
return ret as OUT[] | ||
} | ||
return await new Promise<OUT[]>((resolve, reject) => { | ||
@@ -206,1 +166,74 @@ const next = (): void => { | ||
} | ||
/** | ||
pMap with serial (non-concurrent) execution. | ||
*/ | ||
async function pMap1<IN, OUT>( | ||
items: IN[], | ||
mapper: AbortableAsyncMapper<IN, OUT>, | ||
errorMode: ErrorMode, | ||
logger: CommonLogger | null, | ||
): Promise<OUT[]> { | ||
let i = 0 | ||
const ret: OUT[] = [] | ||
const errors: Error[] = [] | ||
for (const item of items) { | ||
try { | ||
const r = await mapper(item, i++) | ||
if (r === END) break | ||
if (r !== SKIP) ret.push(r) | ||
} catch (err) { | ||
if (errorMode === ErrorMode.THROW_IMMEDIATELY) throw err | ||
if (errorMode === ErrorMode.THROW_AGGREGATED) { | ||
errors.push(err as Error) | ||
} else { | ||
// otherwise, suppress (but still log via logger) | ||
logger?.error(err) | ||
} | ||
} | ||
} | ||
if (errors.length) { | ||
throw new AggregateError(errors, `pMap resulted in ${errors.length} error(s)`) | ||
} | ||
return ret | ||
} | ||
/** | ||
pMap with fully concurrent execution, like Promise.all | ||
*/ | ||
async function pMapAll<IN, OUT>( | ||
items: IN[], | ||
mapper: AbortableAsyncMapper<IN, OUT>, | ||
errorMode: ErrorMode, | ||
logger: CommonLogger | null, | ||
): Promise<OUT[]> { | ||
if (errorMode === ErrorMode.THROW_IMMEDIATELY) { | ||
return (await Promise.all(items.map((item, i) => mapper(item, i)))).filter( | ||
r => r !== SKIP && r !== END, | ||
) as OUT[] | ||
} | ||
const ret: OUT[] = [] | ||
const errors: Error[] = [] | ||
for (const r of await Promise.allSettled(items.map((item, i) => mapper(item, i)))) { | ||
if (r.status === 'fulfilled') { | ||
if (r.value === END) break | ||
if (r.value !== SKIP) ret.push(r.value) | ||
} else if (errorMode === ErrorMode.THROW_AGGREGATED) { | ||
errors.push(r.reason) | ||
} else { | ||
// otherwise, suppress (but still log via logger) | ||
logger?.error(r.reason) | ||
} | ||
} | ||
if (errors.length) { | ||
throw new AggregateError(errors, `pMap resulted in ${errors.length} error(s)`) | ||
} | ||
return ret | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1005232
30116