Comparing version 5.0.0 to 6.0.0
@@ -1,65 +0,51 @@ | ||
import PCancelable = require('p-cancelable'); | ||
import AggregateError = require('aggregate-error'); | ||
import PCancelable from 'p-cancelable'; | ||
type AggregateError_ = AggregateError; | ||
type AggregateErrorConstructor = typeof AggregateError; | ||
export type Value<T> = T | PromiseLike<T>; | ||
export type CancelablePromise<T> = PCancelable<T>; | ||
declare namespace pSome { | ||
type Value<T> = T | PromiseLike<T>; | ||
type CancelablePromise<ValueType> = PCancelable<ValueType>; | ||
export class FilterError extends Error {} | ||
interface Options<T> { | ||
/** | ||
Number of promises from `input` that have to be fulfilled until the returned promise is fulfilled. Minimum: `1`. | ||
*/ | ||
readonly count: number; | ||
export interface Options<T> { | ||
/** | ||
Number of promises from `input` that have to be fulfilled until the returned promise is fulfilled. Minimum: `1`. | ||
*/ | ||
readonly count: number; | ||
/** | ||
Used to filter out values that don't satisfy a condition. | ||
/** | ||
Used to filter out values that don't satisfy a condition. | ||
@param value - The value resolved by the promise. | ||
*/ | ||
readonly filter?: (value: T) => boolean; | ||
} | ||
type AggregateError = AggregateError_; | ||
interface FilterError extends Error {} | ||
@param value - The value resolved by the promise. | ||
*/ | ||
readonly filter?: (value: T) => boolean; | ||
} | ||
declare const pSome: { | ||
/** | ||
Wait for a specified number of promises to be fulfilled. | ||
/** | ||
Wait for a specified number of promises to be fulfilled. | ||
@param values - An `Iterable` collection of promises/values to wait for. If you pass in cancelable promises, specifically promises with a `.cancel()` method, that method will be called for the promises that are still unfulfilled when the returned `Promise` is either fulfilled or rejected. | ||
@returns A [cancelable `Promise`](https://github.com/sindresorhus/p-cancelable) that is fulfilled when `count` promises from `input` are fulfilled. The fulfilled value is an `Array` of the values from the `input` promises in the order they were fulfilled. If it becomes impossible to satisfy `count`, for example, too many promises rejected, it will reject with an [`AggregateError`](https://github.com/sindresorhus/aggregate-error) error. | ||
@param values - An `Iterable` collection of promises/values to wait for. If you pass in cancelable promises, specifically promises with a `.cancel()` method, that method will be called for the promises that are still unfulfilled when the returned `Promise` is either fulfilled or rejected. | ||
@returns A [cancelable `Promise`](https://github.com/sindresorhus/p-cancelable) that is fulfilled when `count` promises from `input` are fulfilled. The fulfilled value is an `Array` of the values from the `input` promises in the order they were fulfilled. If it becomes impossible to satisfy `count`, for example, too many promises rejected, it will reject with an [`AggregateError`](https://github.com/sindresorhus/aggregate-error) error. | ||
@example | ||
``` | ||
import got = require('got'); | ||
import pSome = require('p-some'); | ||
@example | ||
``` | ||
import got from 'got'; | ||
import pSome from 'p-some'; | ||
(async () => { | ||
const input = [ | ||
got.head('github.com').then(() => 'github'), | ||
got.head('google.com').then(() => 'google'), | ||
got.head('twitter.com').then(() => 'twitter'), | ||
got.head('medium.com').then(() => 'medium') | ||
]; | ||
const input = [ | ||
got.head('github.com').then(() => 'github'), | ||
got.head('google.com').then(() => 'google'), | ||
got.head('twitter.com').then(() => 'twitter'), | ||
got.head('medium.com').then(() => 'medium') | ||
]; | ||
const [first, second] = await pSome(input, {count: 2}); | ||
const [first, second] = await pSome(input, {count: 2}); | ||
console.log(first, second); | ||
//=> 'google twitter' | ||
})(); | ||
``` | ||
*/ | ||
<T>( | ||
values: Iterable<pSome.Value<T>>, | ||
options: pSome.Options<T> | ||
): pSome.CancelablePromise<T[]>; | ||
console.log(first, second); | ||
//=> 'google twitter' | ||
``` | ||
*/ | ||
export default function pSome<T>( | ||
values: Iterable<Value<T>>, | ||
options: Options<T> | ||
): CancelablePromise<T[]>; | ||
AggregateError: AggregateErrorConstructor; | ||
FilterError: pSome.FilterError; | ||
}; | ||
export = pSome; | ||
export {default as AggregateError} from 'aggregate-error'; |
130
index.js
@@ -1,84 +0,84 @@ | ||
'use strict'; | ||
const AggregateError = require('aggregate-error'); | ||
const PCancelable = require('p-cancelable'); | ||
import AggregateError from 'aggregate-error'; | ||
import PCancelable from 'p-cancelable'; | ||
class FilterError extends Error { } | ||
export class FilterError extends Error {} | ||
const pSome = (iterable, options) => new PCancelable((resolve, reject, onCancel) => { | ||
const { | ||
count, | ||
filter = () => true | ||
} = options; | ||
// Important: Cannot use the `async` keyword. | ||
export default function pSome(iterable, options) { | ||
return new PCancelable((resolve, reject, onCancel) => { | ||
const { | ||
count, | ||
filter = () => true | ||
} = options; | ||
if (!Number.isFinite(count)) { | ||
reject(new TypeError(`Expected a finite number, got ${typeof options.count}`)); | ||
return; | ||
} | ||
if (!Number.isFinite(count)) { | ||
reject(new TypeError(`Expected a finite number, got ${typeof options.count}`)); | ||
return; | ||
} | ||
const values = []; | ||
const errors = []; | ||
let elementCount = 0; | ||
let isSettled = false; | ||
const values = []; | ||
const errors = []; | ||
let elementCount = 0; | ||
let isSettled = false; | ||
const completed = new Set(); | ||
const maybeSettle = () => { | ||
if (values.length === count) { | ||
resolve(values); | ||
isSettled = true; | ||
} | ||
const completed = new Set(); | ||
const maybeSettle = () => { | ||
if (values.length === count) { | ||
resolve(values); | ||
isSettled = true; | ||
} | ||
if (elementCount - errors.length < count) { | ||
reject(new AggregateError(errors)); | ||
isSettled = true; | ||
} | ||
if (elementCount - errors.length < count) { | ||
reject(new AggregateError(errors)); | ||
isSettled = true; | ||
} | ||
return isSettled; | ||
}; | ||
return isSettled; | ||
}; | ||
const cancelPending = () => { | ||
for (const promise of iterable) { | ||
if (!completed.has(promise) && typeof promise.cancel === 'function') { | ||
promise.cancel(); | ||
const cancelPending = () => { | ||
for (const promise of iterable) { | ||
if (!completed.has(promise) && typeof promise.cancel === 'function') { | ||
promise.cancel(); | ||
} | ||
} | ||
} | ||
}; | ||
}; | ||
onCancel(cancelPending); | ||
onCancel(cancelPending); | ||
for (const element of iterable) { | ||
elementCount++; | ||
for (const element of iterable) { | ||
elementCount++; | ||
(async () => { | ||
try { | ||
const value = await element; | ||
(async () => { | ||
try { | ||
const value = await element; | ||
if (isSettled) { | ||
return; | ||
} | ||
if (isSettled) { | ||
return; | ||
} | ||
if (!filter(value)) { | ||
throw new FilterError('Value does not satisfy filter'); | ||
} | ||
if (!filter(value)) { | ||
throw new FilterError('Value does not satisfy filter'); | ||
} | ||
values.push(value); | ||
} catch (error) { | ||
errors.push(error); | ||
} finally { | ||
completed.add(element); | ||
values.push(value); | ||
} catch (error) { | ||
errors.push(error); | ||
} finally { | ||
completed.add(element); | ||
if (!isSettled && maybeSettle()) { | ||
cancelPending(); | ||
if (!isSettled && maybeSettle()) { | ||
cancelPending(); | ||
} | ||
} | ||
} | ||
})(); | ||
} | ||
})(); | ||
} | ||
if (count > elementCount) { | ||
reject(new RangeError(`Expected input to contain at least ${options.count} items, but contains ${elementCount} items`)); | ||
cancelPending(); | ||
} | ||
}); | ||
if (count > elementCount) { | ||
reject(new RangeError(`Expected input to contain at least ${options.count} items, but contains ${elementCount} items`)); | ||
cancelPending(); | ||
} | ||
}); | ||
} | ||
module.exports = pSome; | ||
module.exports.AggregateError = AggregateError; | ||
module.exports.FilterError = FilterError; | ||
export {AggregateError}; |
{ | ||
"name": "p-some", | ||
"version": "5.0.0", | ||
"version": "6.0.0", | ||
"description": "Wait for a specified number of promises to be fulfilled", | ||
@@ -13,4 +13,6 @@ "license": "MIT", | ||
}, | ||
"type": "module", | ||
"exports": "./index.js", | ||
"engines": { | ||
"node": ">=10" | ||
"node": ">=12.20" | ||
}, | ||
@@ -41,11 +43,11 @@ "scripts": { | ||
"dependencies": { | ||
"aggregate-error": "^3.0.0", | ||
"p-cancelable": "^2.0.0" | ||
"aggregate-error": "^4.0.0", | ||
"p-cancelable": "^3.0.0" | ||
}, | ||
"devDependencies": { | ||
"ava": "^1.4.1", | ||
"delay": "^4.1.0", | ||
"tsd": "^0.11.0", | ||
"xo": "^0.26.1" | ||
"ava": "^3.15.0", | ||
"delay": "^5.0.0", | ||
"tsd": "^0.16.0", | ||
"xo": "^0.40.1" | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
# p-some [![Build Status](https://travis-ci.org/sindresorhus/p-some.svg?branch=master)](https://travis-ci.org/sindresorhus/p-some) | ||
# p-some | ||
@@ -18,18 +18,16 @@ > Wait for a specified number of promises to be fulfilled | ||
```js | ||
const got = require('got'); | ||
const pSome = require('p-some'); | ||
import got from 'got'; | ||
import pSome from 'p-some'; | ||
(async () => { | ||
const input = [ | ||
got.head('github.com').then(() => 'github'), | ||
got.head('google.com').then(() => 'google'), | ||
got.head('twitter.com').then(() => 'twitter'), | ||
got.head('medium.com').then(() => 'medium') | ||
]; | ||
const input = [ | ||
got.head('github.com').then(() => 'github'), | ||
got.head('google.com').then(() => 'google'), | ||
got.head('twitter.com').then(() => 'twitter'), | ||
got.head('medium.com').then(() => 'medium') | ||
]; | ||
const [first, second] = await pSome(input, {count: 2}); | ||
const [first, second] = await pSome(input, {count: 2}); | ||
console.log(first, second); | ||
//=> 'google twitter' | ||
})(); | ||
console.log(first, second); | ||
//=> 'google twitter' | ||
``` | ||
@@ -69,7 +67,7 @@ | ||
### pSome.AggregateError | ||
### AggregateError | ||
Exposed for instance checking. | ||
### pSome.FilterError | ||
### FilterError | ||
@@ -81,2 +79,3 @@ Exposed for instance checking. | ||
- [p-any](https://github.com/sindresorhus/p-any) - Wait for any promise to be fulfilled | ||
- [p-one](https://github.com/kevva/p-one) - Return `true` if any promise passes a testing function, similar to `Array#some` | ||
- [More…](https://github.com/sindresorhus/promise-fun) |
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
Yes
7737
107
79
+ Addedaggregate-error@4.0.1(transitive)
+ Addedclean-stack@4.2.0(transitive)
+ Addedescape-string-regexp@5.0.0(transitive)
+ Addedindent-string@5.0.0(transitive)
+ Addedp-cancelable@3.0.0(transitive)
- Removedaggregate-error@3.1.0(transitive)
- Removedclean-stack@2.2.0(transitive)
- Removedindent-string@4.0.0(transitive)
- Removedp-cancelable@2.1.1(transitive)
Updatedaggregate-error@^4.0.0
Updatedp-cancelable@^3.0.0