diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c1870cf..441975c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,12 +10,10 @@ jobs: fail-fast: false matrix: node-version: - - 14 - - 12 - - 10 + - 16 steps: - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - run: npm install diff --git a/index.d.ts b/index.d.ts index f348d7f..caae030 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,34 +1,34 @@ -declare namespace pLimit { - interface Limit { - /** - The number of promises that are currently running. - */ - readonly activeCount: number; - - /** - The number of promises that are waiting to run (i.e. their internal `fn` was not called yet). - */ - readonly pendingCount: number; - - /** - Discard pending promises that are waiting to run. - - This might be useful if you want to teardown the queue at the end of your program's lifecycle or discard any function calls referencing an intermediary state of your app. - - Note: This does not cancel promises that are already running. - */ - clearQueue: () => void; - - /** - @param fn - Promise-returning/async function. - @param arguments - Any arguments to pass through to `fn`. Support for passing arguments on to the `fn` is provided in order to be able to avoid creating unnecessary closures. You probably don't need this optimization unless you're pushing a lot of functions. - @returns The promise returned by calling `fn(...arguments)`. - */ - ( - fn: (...arguments: Arguments) => PromiseLike | ReturnType, - ...arguments: Arguments - ): Promise; - } +/* eslint-disable @typescript-eslint/member-ordering */ + +export interface LimitFunction { + /** + The number of promises that are currently running. + */ + readonly activeCount: number; + + /** + The number of promises that are waiting to run (i.e. their internal `fn` was not called yet). + */ + readonly pendingCount: number; + + /** + Discard pending promises that are waiting to run. + + This might be useful if you want to teardown the queue at the end of your program's lifecycle or discard any function calls referencing an intermediary state of your app. + + Note: This does not cancel promises that are already running. + */ + clearQueue: () => void; + + /** + @param fn - Promise-returning/async function. + @param arguments - Any arguments to pass through to `fn`. Support for passing arguments on to the `fn` is provided in order to be able to avoid creating unnecessary closures. You probably don't need this optimization unless you're pushing a lot of functions. + @returns The promise returned by calling `fn(...arguments)`. + */ + ( + fn: (...arguments: Arguments) => PromiseLike | ReturnType, + ...arguments: Arguments + ): Promise; } /** @@ -37,6 +37,4 @@ Run multiple promise-returning & async functions with limited concurrency. @param concurrency - Concurrency limit. Minimum: `1`. @returns A `limit` function. */ -declare function pLimit(concurrency: number): pLimit.Limit; - -export = pLimit; +export default function pLimit(concurrency: number): LimitFunction; diff --git a/index.js b/index.js index 0fd024b..b54b99b 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,7 @@ -'use strict'; -const Queue = require('yocto-queue'); +import Queue from 'yocto-queue'; -const pLimit = concurrency => { - if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) { +export default function pLimit(concurrency) { + if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) { throw new TypeError('Expected `concurrency` to be a number from 1 and up'); } @@ -32,7 +31,7 @@ const pLimit = concurrency => { }; const enqueue = (fn, resolve, args) => { - queue.enqueue(run.bind(null, fn, resolve, args)); + queue.enqueue(run.bind(undefined, fn, resolve, args)); (async () => { // This function needs to wait until the next microtask before comparing @@ -53,19 +52,17 @@ const pLimit = concurrency => { Object.defineProperties(generator, { activeCount: { - get: () => activeCount + get: () => activeCount, }, pendingCount: { - get: () => queue.size + get: () => queue.size, }, clearQueue: { value: () => { queue.clear(); - } - } + }, + }, }); return generator; -}; - -module.exports = pLimit; +} diff --git a/index.test-d.ts b/index.test-d.ts index a94e1ef..14ba301 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,18 +1,18 @@ import {expectType} from 'tsd'; -import pLimit = require('.'); +import pLimit from './index.js'; const limit = pLimit(1); const input = [ limit(async () => 'foo'), limit(async () => 'bar'), - limit(async () => undefined) + limit(async () => undefined), ]; expectType>>(Promise.all(input)); -expectType>(limit((a: string) => '', 'test')); -expectType>(limit(async (a: string, b: number) => '', 'test', 1)); +expectType>(limit((_a: string) => '', 'test')); +expectType>(limit(async (_a: string, _b: number) => '', 'test', 1)); expectType(limit.activeCount); expectType(limit.pendingCount); diff --git a/package.json b/package.json index 7651473..84cc6ab 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,10 @@ "email": "sindresorhus@gmail.com", "url": "https://sindresorhus.com" }, + "type": "module", + "exports": "./index.js", "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "scripts": { "test": "xo && ava && tsd" @@ -38,15 +40,15 @@ "bluebird" ], "dependencies": { - "yocto-queue": "^0.1.0" + "yocto-queue": "^1.0.0" }, "devDependencies": { - "ava": "^2.4.0", - "delay": "^4.4.0", - "in-range": "^2.0.0", - "random-int": "^2.0.1", - "time-span": "^4.0.0", - "tsd": "^0.13.1", - "xo": "^0.35.0" + "ava": "^3.15.0", + "delay": "^5.0.0", + "in-range": "^3.0.0", + "random-int": "^3.0.0", + "time-span": "^5.0.0", + "tsd": "^0.17.0", + "xo": "^0.44.0" } } diff --git a/readme.md b/readme.md index b283c1e..b02253b 100644 --- a/readme.md +++ b/readme.md @@ -11,7 +11,7 @@ $ npm install p-limit ## Usage ```js -const pLimit = require('p-limit'); +import pLimit from 'p-limit'; const limit = pLimit(1); @@ -21,11 +21,9 @@ const input = [ limit(() => doSomething()) ]; -(async () => { - // Only one promise is run at once - const result = await Promise.all(input); - console.log(result); -})(); +// Only one promise is run at once +const result = await Promise.all(input); +console.log(result); ``` ## API diff --git a/test.js b/test.js index 21976b8..fd61a97 100644 --- a/test.js +++ b/test.js @@ -3,13 +3,13 @@ import delay from 'delay'; import inRange from 'in-range'; import timeSpan from 'time-span'; import randomInt from 'random-int'; -import pLimit from '.'; +import pLimit from './index.js'; test('concurrency: 1', async t => { const input = [ [10, 300], [20, 200], - [30, 100] + [30, 100], ]; const end = timeSpan(); @@ -57,7 +57,7 @@ test('continues after sync throw', async t => { }), limit(() => { ran = true; - }) + }), ]; await Promise.all(promises).catch(() => {}); @@ -86,7 +86,7 @@ test('does not ignore errors', async t => { }), limit(async () => { await delay(50); - }) + }), ]; await t.throwsAsync(Promise.all(promises), {is: error});