Skip to content

Commit

Permalink
Require Node.js 12 and move to ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Apr 6, 2021
1 parent 4f86930 commit 458618e
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 153 deletions.
3 changes: 0 additions & 3 deletions .github/funding.yml

This file was deleted.

1 change: 0 additions & 1 deletion .github/workflows/main.yml
Expand Up @@ -12,7 +12,6 @@ jobs:
node-version:
- 14
- 12
- 10
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
Expand Down
168 changes: 78 additions & 90 deletions index.d.ts
@@ -1,113 +1,101 @@
declare class TimeoutErrorClass extends Error {
/* eslint-disable import/export */

export class TimeoutError extends Error {
readonly name: 'TimeoutError';
constructor(message?: string);
}

declare namespace pTimeout {
type TimeoutError = TimeoutErrorClass;

type Options = {
/**
Custom implementations for the `setTimeout` and `clearTimeout` functions.
Useful for testing purposes, in particular to work around [`sinon.useFakeTimers()`](https://sinonjs.org/releases/latest/fake-timers/).
@example
```
import pTimeout = require('p-timeout');
import sinon = require('sinon');
(async () => {
const originalSetTimeout = setTimeout;
const originalClearTimeout = clearTimeout;
sinon.useFakeTimers();
// Use `pTimeout` without being affected by `sinon.useFakeTimers()`:
await pTimeout(doSomething(), 2000, undefined, {
customTimers: {
setTimeout: originalSetTimeout,
clearTimeout: originalClearTimeout
}
});
})();
```
*/
readonly customTimers?: {
setTimeout: typeof global.setTimeout;
clearTimeout: typeof global.clearTimeout;
};
};
}

interface ClearablePromise<T> extends Promise<T>{
export interface ClearablePromise<T> extends Promise<T>{
/**
Clear the timeout.
*/
clear: () => void;
}

declare const pTimeout: {
TimeoutError: typeof TimeoutErrorClass;

default: typeof pTimeout;

export type Options = {
/**
Timeout a promise after a specified amount of time.
If you pass in a cancelable promise, specifically a promise with a `.cancel()` method, that method will be called when the `pTimeout` promise times out.
Custom implementations for the `setTimeout` and `clearTimeout` functions.
@param input - Promise to decorate.
@param milliseconds - Milliseconds before timing out.
@param message - Specify a custom error message or error. If you do a custom error, it's recommended to sub-class `pTimeout.TimeoutError`. Default: `'Promise timed out after 50 milliseconds'`.
@returns A decorated `input` that times out after `milliseconds` time. It has a `.clear()` method that clears the timeout.
Useful for testing purposes, in particular to work around [`sinon.useFakeTimers()`](https://sinonjs.org/releases/latest/fake-timers/).
@example
```
import delay = require('delay');
import pTimeout = require('p-timeout');
const delayedPromise = delay(200);
pTimeout(delayedPromise, 50).then(() => 'foo');
//=> [TimeoutError: Promise timed out after 50 milliseconds]
```
*/
<ValueType>(
input: PromiseLike<ValueType>,
milliseconds: number,
message?: string | Error,
options?: pTimeout.Options
): ClearablePromise<ValueType>;
import pTimeout from 'p-timeout';
import sinon from 'sinon';
/**
Timeout a promise after a specified amount of time.
const originalSetTimeout = setTimeout;
const originalClearTimeout = clearTimeout;
If you pass in a cancelable promise, specifically a promise with a `.cancel()` method, that method will be called when the `pTimeout` promise times out.
sinon.useFakeTimers();
@param input - Promise to decorate.
@param milliseconds - Milliseconds before timing out. Passing `Infinity` will cause it to never time out.
@param fallback - Do something other than rejecting with an error on timeout. You could for example retry.
@returns A decorated `input` that times out after `milliseconds` time. It has a `.clear()` method that clears the timeout.
@example
```
import delay = require('delay');
import pTimeout = require('p-timeout');
const delayedPromise = () => delay(200);
pTimeout(delayedPromise(), 50, () => {
return pTimeout(delayedPromise(), 300);
// Use `pTimeout` without being affected by `sinon.useFakeTimers()`:
await pTimeout(doSomething(), 2000, undefined, {
customTimers: {
setTimeout: originalSetTimeout,
clearTimeout: originalClearTimeout
}
});
```
*/
<ValueType, ReturnType>(
input: PromiseLike<ValueType>,
milliseconds: number,
fallback: () => ReturnType | Promise<ReturnType>,
options?: pTimeout.Options
): ClearablePromise<ValueType | ReturnType>;
readonly customTimers?: {
setTimeout: typeof global.setTimeout;
clearTimeout: typeof global.clearTimeout;
};
};

export = pTimeout;
/**
Timeout a promise after a specified amount of time.
If you pass in a cancelable promise, specifically a promise with a `.cancel()` method, that method will be called when the `pTimeout` promise times out.
@param input - Promise to decorate.
@param milliseconds - Milliseconds before timing out.
@param message - Specify a custom error message or error. If you do a custom error, it's recommended to sub-class `pTimeout.TimeoutError`. Default: `'Promise timed out after 50 milliseconds'`.
@returns A decorated `input` that times out after `milliseconds` time. It has a `.clear()` method that clears the timeout.
@example
```
import {setTimeout} from 'timers/promises';
import pTimeout from 'p-timeout';
const delayedPromise = setTimeout(200);
await pTimeout(delayedPromise, 50);
//=> [TimeoutError: Promise timed out after 50 milliseconds]
```
*/
export default function pTimeout<ValueType>(
input: PromiseLike<ValueType>,
milliseconds: number,
message?: string | Error,
options?: Options
): ClearablePromise<ValueType>;

/**
Timeout a promise after a specified amount of time.
If you pass in a cancelable promise, specifically a promise with a `.cancel()` method, that method will be called when the `pTimeout` promise times out.
@param input - Promise to decorate.
@param milliseconds - Milliseconds before timing out. Passing `Infinity` will cause it to never time out.
@param fallback - Do something other than rejecting with an error on timeout. You could for example retry.
@returns A decorated `input` that times out after `milliseconds` time. It has a `.clear()` method that clears the timeout.
@example
```
import {setTimeout} from 'timers/promises';
import pTimeout from 'p-timeout';
const delayedPromise = () => setTimeout(200);
await pTimeout(delayedPromise(), 50, () => {
return pTimeout(delayedPromise(), 300);
});
```
*/
export default function pTimeout<ValueType, ReturnType>(
input: PromiseLike<ValueType>,
milliseconds: number,
fallback: () => ReturnType | Promise<ReturnType>,
options?: Options
): ClearablePromise<ValueType | ReturnType>;
16 changes: 4 additions & 12 deletions index.js
@@ -1,20 +1,18 @@
'use strict';

class TimeoutError extends Error {
export class TimeoutError extends Error {
constructor(message) {
super(message);
this.name = 'TimeoutError';
}
}

const pTimeout = (promise, milliseconds, fallback, options) => {
export default function pTimeout(promise, milliseconds, fallback, options) {
let timer;
const cancelablePromise = new Promise((resolve, reject) => {
if (typeof milliseconds !== 'number' || milliseconds < 0) {
throw new TypeError('Expected `milliseconds` to be a positive number');
}

if (milliseconds === Infinity) {
if (milliseconds === Number.POSITIVE_INFINITY) {
resolve(promise);
return;
}
Expand Down Expand Up @@ -62,10 +60,4 @@ const pTimeout = (promise, milliseconds, fallback, options) => {
};

return cancelablePromise;
};

module.exports = pTimeout;
// TODO: Remove this for the next major release
module.exports.default = pTimeout;

module.exports.TimeoutError = TimeoutError;
}
6 changes: 3 additions & 3 deletions index.test-d.ts
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-floating-promises */
import {expectType, expectError} from 'tsd';
import pTimeout = require('.');
import {TimeoutError} from '.';
import pTimeout, {TimeoutError} from './index.js';

const delayedPromise: () => Promise<string> = async () => {
return new Promise(resolve => {
Expand All @@ -11,7 +11,7 @@ const delayedPromise: () => Promise<string> = async () => {
};

pTimeout(delayedPromise(), 50).then(() => 'foo');
pTimeout(delayedPromise(), 50, () => {
pTimeout(delayedPromise(), 50, async () => {
return pTimeout(delayedPromise(), 300);
});
pTimeout(delayedPromise(), 50).then(value => expectType<string>(value));
Expand Down
19 changes: 11 additions & 8 deletions package.json
Expand Up @@ -4,13 +4,16 @@
"description": "Timeout a promise after a specified amount of time",
"license": "MIT",
"repository": "sindresorhus/p-timeout",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=10"
"node": ">=12"
},
"scripts": {
"test": "xo && ava && tsd"
Expand All @@ -33,12 +36,12 @@
"bluebird"
],
"devDependencies": {
"ava": "^2.4.0",
"delay": "^4.4.0",
"p-cancelable": "^2.0.0",
"tsd": "^0.13.1",
"xo": "^0.35.0",
"in-range": "^2.0.0",
"time-span": "^4.0.0"
"ava": "^3.15.0",
"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"
}
}
48 changes: 23 additions & 25 deletions readme.md
Expand Up @@ -11,12 +11,12 @@ $ npm install p-timeout
## Usage

```js
const delay = require('delay');
const pTimeout = require('p-timeout');
import {setTimeout} from 'timers/promises';
import pTimeout from 'p-timeout';

const delayedPromise = delay(200);
const delayedPromise = setTimeout(200);

pTimeout(delayedPromise, 50).then(() => 'foo');
await pTimeout(delayedPromise, 50);
//=> [TimeoutError: Promise timed out after 50 milliseconds]
```

Expand Down Expand Up @@ -61,12 +61,12 @@ Do something other than rejecting with an error on timeout.
You could for example retry:

```js
const delay = require('delay');
const pTimeout = require('p-timeout');
import {setTimeout} from 'timers/promises';
import pTimeout from 'p-timeout';

const delayedPromise = () => delay(200);
const delayedPromise = () => setTimeout(200);

pTimeout(delayedPromise(), 50, () => {
await pTimeout(delayedPromise(), 50, () => {
return pTimeout(delayedPromise(), 300);
});
```
Expand All @@ -86,23 +86,21 @@ Useful for testing purposes, in particular to work around [`sinon.useFakeTimers(
Example:

```js
const pTimeout = require('p-timeout');
const sinon = require('sinon');

(async () => {
const originalSetTimeout = setTimeout;
const originalClearTimeout = clearTimeout;

sinon.useFakeTimers();

// Use `pTimeout` without being affected by `sinon.useFakeTimers()`:
await pTimeout(doSomething(), 2000, undefined, {
customTimers: {
setTimeout: originalSetTimeout,
clearTimeout: originalClearTimeout
}
});
})();
import {setTimeout} from 'timers/promises';
import pTimeout from 'p-timeout';

const originalSetTimeout = setTimeout;
const originalClearTimeout = clearTimeout;

sinon.useFakeTimers();

// Use `pTimeout` without being affected by `sinon.useFakeTimers()`:
await pTimeout(doSomething(), 2000, undefined, {
customTimers: {
setTimeout: originalSetTimeout,
clearTimeout: originalClearTimeout
}
});
```

### pTimeout.TimeoutError
Expand Down

0 comments on commit 458618e

Please sign in to comment.