From eb1730ba0c84aa5eabbc7ce2def5f1a71fc5e700 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 25 Jul 2022 18:24:32 +0200 Subject: [PATCH] Require Node.js 14 Fixes #27 --- .github/workflows/main.yml | 7 ++++--- index.d.ts | 4 ++-- index.js | 32 ++++++++++++++++---------------- index.test-d.ts | 24 +++++++++++++----------- package.json | 13 +++++++------ readme.md | 10 +++++----- test.js | 14 +++++++------- 7 files changed, 54 insertions(+), 50 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 41fe626..d50ada6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -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 diff --git a/index.d.ts b/index.d.ts index 01b6d1f..375d7b0 100644 --- a/index.d.ts +++ b/index.d.ts @@ -25,7 +25,7 @@ export type Options = { @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); diff --git a/index.js b/index.js index 648ce7e..ebd6c2d 100644 --- a/index.js +++ b/index.js @@ -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; }; diff --git a/index.test-d.ts b/index.test-d.ts index 54ddd6a..3a54965 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -10,13 +10,15 @@ const delayedPromise: () => Promise = 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(value)); -pTimeout(delayedPromise(), {milliseconds: 50, message: 'error'}).then(value => - expectType(value) -); -pTimeout(delayedPromise(), {milliseconds: 50, message: new Error('error')}).then(value => - expectType(value) -); +pTimeout(delayedPromise(), {milliseconds: 50}).then(value => { + expectType(value); +}); +pTimeout(delayedPromise(), {milliseconds: 50, message: 'error'}).then(value => { + expectType(value); +}); +pTimeout(delayedPromise(), {milliseconds: 50, message: new Error('error')}).then(value => { + expectType(value); +}); pTimeout(delayedPromise(), {milliseconds: 50, fallback: async () => 10}).then(value => { expectType(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 diff --git a/package.json b/package.json index 9d2d778..8a5e9fd 100644 --- a/package.json +++ b/package.json @@ -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" } } diff --git a/readme.md b/readme.md index 48abb70..12c7c52 100644 --- a/readme.md +++ b/readme.md @@ -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; diff --git a/test.js b/test.js index 0488bdd..00088c9 100644 --- a/test.js +++ b/test.js @@ -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', }); }); }