Require Node.js 14

Fixes #27
This commit is contained in:
Sindre Sorhus 2022-07-25 18:24:32 +02:00
parent d7920cae0a
commit eb1730ba0c
7 changed files with 54 additions and 50 deletions

View File

@ -10,11 +10,12 @@ jobs:
fail-fast: false
matrix:
node-version:
- 18
- 16
- 14
- 12
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install

4
index.d.ts vendored
View File

@ -25,7 +25,7 @@ export type Options<ReturnType> = {
@example
```
import {setTimeout} from 'timers/promises';
import {setTimeout} from 'node:timers/promises';
import pTimeout from 'p-timeout';
const delayedPromise = () => setTimeout(200);
@ -116,7 +116,7 @@ If you pass in a cancelable promise, specifically a promise with a `.cancel()` m
@example
```
import {setTimeout} from 'timers/promises';
import {setTimeout} from 'node:timers/promises';
import pTimeout from 'p-timeout';
const delayedPromise = () => setTimeout(200);

View File

@ -20,27 +20,32 @@ export class AbortError extends Error {
/**
TODO: Remove AbortError and just throw DOMException when targeting Node 18.
*/
const getDOMException = errorMessage => globalThis.DOMException === undefined ?
new AbortError(errorMessage) :
new DOMException(errorMessage);
const getDOMException = errorMessage => globalThis.DOMException === undefined
? new AbortError(errorMessage)
: new DOMException(errorMessage);
/**
TODO: Remove below function and just 'reject(signal.reason)' when targeting Node 18.
*/
const getAbortedReason = signal => {
const reason = signal.reason === undefined ?
getDOMException('This operation was aborted.') :
signal.reason;
const reason = signal.reason === undefined
? getDOMException('This operation was aborted.')
: signal.reason;
return reason instanceof Error ? reason : getDOMException(reason);
};
export default function pTimeout(promise, options) {
const {
milliseconds,
fallback,
message,
customTimers = {setTimeout, clearTimeout},
} = options;
let timer;
const cancelablePromise = new Promise((resolve, reject) => {
const {milliseconds, fallback, message} = options;
if (typeof milliseconds !== 'number' || Math.sign(milliseconds) !== 1) {
throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${milliseconds}\``);
}
@ -50,11 +55,6 @@ export default function pTimeout(promise, options) {
return;
}
options = {
customTimers: {setTimeout, clearTimeout},
...options
};
if (options.signal) {
const {signal} = options;
if (signal.aborted) {
@ -66,7 +66,7 @@ export default function pTimeout(promise, options) {
});
}
timer = options.customTimers.setTimeout.call(undefined, () => {
timer = customTimers.setTimeout.call(undefined, () => {
if (fallback) {
try {
resolve(fallback());
@ -93,13 +93,13 @@ export default function pTimeout(promise, options) {
} catch (error) {
reject(error);
} finally {
options.customTimers.clearTimeout.call(undefined, timer);
customTimers.clearTimeout.call(undefined, timer);
}
})();
});
cancelablePromise.clear = () => {
clearTimeout(timer);
customTimers.clearTimeout.call(undefined, timer);
timer = undefined;
};

View File

@ -10,13 +10,15 @@ const delayedPromise: () => Promise<string> = async () => new Promise(resolve =>
pTimeout(delayedPromise(), {milliseconds: 50}).then(() => 'foo');
pTimeout(delayedPromise(), {milliseconds: 50, fallback: async () => pTimeout(delayedPromise(), {milliseconds: 300})});
pTimeout(delayedPromise(), {milliseconds: 50}).then(value => expectType<string>(value));
pTimeout(delayedPromise(), {milliseconds: 50, message: 'error'}).then(value =>
expectType<string>(value)
);
pTimeout(delayedPromise(), {milliseconds: 50, message: new Error('error')}).then(value =>
expectType<string>(value)
);
pTimeout(delayedPromise(), {milliseconds: 50}).then(value => {
expectType<string>(value);
});
pTimeout(delayedPromise(), {milliseconds: 50, message: 'error'}).then(value => {
expectType<string>(value);
});
pTimeout(delayedPromise(), {milliseconds: 50, message: new Error('error')}).then(value => {
expectType<string>(value);
});
pTimeout(delayedPromise(), {milliseconds: 50, fallback: async () => 10}).then(value => {
expectType<string | number>(value);
});
@ -34,8 +36,8 @@ expectError(pTimeout(delayedPromise(), {
milliseconds: 50,
fallback: () => 10,
customTimers: {
setTimeout
}
setTimeout,
},
}));
expectError(pTimeout(delayedPromise(), {
@ -43,8 +45,8 @@ expectError(pTimeout(delayedPromise(), {
fallback: () => 10,
customTimers: {
setTimeout: () => 42, // Invalid `setTimeout` implementation
clearTimeout
}
clearTimeout,
},
}));
expectError(pTimeout(delayedPromise(), {})); // `milliseconds` is required

View File

@ -12,8 +12,9 @@
},
"type": "module",
"exports": "./index.js",
"types": "./index.d.ts",
"engines": {
"node": ">=12"
"node": ">=14.16"
},
"scripts": {
"test": "xo && ava && tsd"
@ -36,12 +37,12 @@
"bluebird"
],
"devDependencies": {
"ava": "^3.15.0",
"ava": "^4.3.1",
"delay": "^5.0.0",
"in-range": "^3.0.0",
"p-cancelable": "^2.1.0",
"time-span": "^4.0.0",
"tsd": "^0.14.0",
"xo": "^0.38.2"
"p-cancelable": "^4.0.1",
"time-span": "^5.1.0",
"tsd": "^0.22.0",
"xo": "^0.51.0"
}
}

View File

@ -4,14 +4,14 @@
## Install
```
$ npm install p-timeout
```sh
npm install p-timeout
```
## Usage
```js
import {setTimeout} from 'timers/promises';
import {setTimeout} from 'node:timers/promises';
import pTimeout from 'p-timeout';
const delayedPromise = setTimeout(200);
@ -66,7 +66,7 @@ Do something other than rejecting with an error on timeout.
You could for example retry:
```js
import {setTimeout} from 'timers/promises';
import {setTimeout} from 'node:timers/promises';
import pTimeout from 'p-timeout';
const delayedPromise = () => setTimeout(200);
@ -90,7 +90,7 @@ Useful for testing purposes, in particular to work around [`sinon.useFakeTimers(
Example:
```js
import {setTimeout} from 'timers/promises';
import {setTimeout} from 'node:timers/promises';
import pTimeout from 'p-timeout';
const originalSetTimeout = setTimeout;

14
test.js
View File

@ -27,7 +27,7 @@ test('throws when milliseconds is NaN', async t => {
test('handles milliseconds being `Infinity`', async t => {
t.is(
await pTimeout(delay(50, {value: fixture}), {milliseconds: Number.POSITIVE_INFINITY}),
fixture
fixture,
);
});
@ -77,8 +77,8 @@ test('accepts `customTimers` option', async t => {
clearTimeout(timeoutId) {
t.pass();
return clearTimeout(timeoutId);
}
}
},
},
});
});
@ -101,13 +101,13 @@ if (globalThis.AbortController !== undefined) {
const promise = pTimeout(delay(3000), {
milliseconds: 2000,
signal: abortController.signal
signal: abortController.signal,
});
abortController.abort();
await t.throwsAsync(promise, {
name: 'AbortError'
name: 'AbortError',
});
});
@ -118,9 +118,9 @@ if (globalThis.AbortController !== undefined) {
await t.throwsAsync(pTimeout(delay(3000), {
milliseconds: 2000,
signal: abortController.signal
signal: abortController.signal,
}), {
name: 'AbortError'
name: 'AbortError',
});
});
}