-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Changelog: feature
- Loading branch information
Showing
6 changed files
with
117 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { timeout } from "@mrspartak/promises" | ||
import { api } from "./api" | ||
|
||
// Can be used as a race condition | ||
const user = await timeout(api.getUser(), 1000) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
import { to } from "./to"; | ||
import { delay, sleep } from "./delay"; | ||
import { timeout } from "./timeout"; | ||
|
||
export { to, delay, sleep }; | ||
export { to, delay, sleep, timeout }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* Type alias for a promise of type T. | ||
*/ | ||
type TimeoutIn<T> = Promise<T>; | ||
|
||
/** | ||
* Return type for the timeout function. | ||
*/ | ||
type TimeoutOut<T> = Promise<T>; | ||
|
||
/** | ||
* This function ensures that a provided promise is resolved within a specified time. | ||
* If the promise does not resolve within the specified time, an error is thrown. | ||
* | ||
* @template T The type of the value that the input promise resolves to. | ||
* @param {Promise<T>} promise - The promise to be awaited. | ||
* @param {number} ms - The number of milliseconds to wait. | ||
* @param {string} [message] - The error message to throw. | ||
* @returns {Promise<T>} The resolved value of the promise. | ||
* @throws {Error} Throws an error if the input time is not a positive number or if the promise times out. | ||
* | ||
* @includeExample examples/timeout.ts | ||
*/ | ||
export async function timeout<T>(promise: TimeoutIn<T>, ms: number, message?: string): TimeoutOut<T> { | ||
// Validate that the input time is a number | ||
if (typeof ms !== 'number') { | ||
throw new Error('timeout(ms) requires a number as a parameter'); | ||
} | ||
|
||
// Validate that the number is positive | ||
if (ms < 0) { | ||
throw new Error('timeout(ms) requires a positive number as a parameter'); | ||
} | ||
|
||
// Create a timeout promise that rejects after the specified delay | ||
const timeoutPromise = new Promise<T>((_, reject) => { | ||
const timeoutId = setTimeout(() => { | ||
clearTimeout(timeoutId) | ||
reject(new Error(message || 'Timeout')); | ||
}, ms); | ||
}); | ||
|
||
// Return a race between the input promise and the timeout promise | ||
return Promise.race([promise, timeoutPromise]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { describe, expect, it } from "vitest"; | ||
import { timeout } from '../../dist/index.js' | ||
|
||
describe("timeout", () => { | ||
it("must be a function", () => { | ||
expect(typeof timeout).toBe("function"); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { describe, expect, it } from "vitest"; | ||
import { timeout } from '../../src/timeout.js' | ||
import { delay } from '../../src/delay.js' | ||
|
||
describe('timeout', () => { | ||
it('should be a function', () => { | ||
expect(typeof timeout).toBe('function') | ||
}) | ||
|
||
it('should return a promise', () => { | ||
expect(timeout(new Promise((resolve) => resolve('value')), 100) instanceof Promise).toBe(true) | ||
}) | ||
|
||
it('should return the value', async () => { | ||
const value = 'value' | ||
expect(await timeout(new Promise((resolve) => resolve('value')), 100)).toStrictEqual(value) | ||
}) | ||
|
||
it('should throw an error if time is not a number', async () => { | ||
const error = 'timeout(ms) requires a number as a parameter' | ||
// @ts-ignore | ||
await expect(timeout(new Promise((resolve) => resolve('value')), '100')).rejects.toThrowError(error) | ||
}) | ||
|
||
it('should throw an error if time is negative', async () => { | ||
const error = 'timeout(ms) requires a positive number as a parameter' | ||
await expect(timeout(new Promise((resolve) => resolve('value')), -100)).rejects.toThrowError(error) | ||
}) | ||
|
||
it('should throw an error if promise rejects', async () => { | ||
await expect(timeout(new Promise((_, reject) => reject('error')), 100)).rejects.toThrowError('error') | ||
}) | ||
|
||
it('should throw an error if promise times out', async () => { | ||
await expect(timeout(delay(105), 100)).rejects.toThrowError('Timeout') | ||
}) | ||
|
||
it('should throw an error if promise times out with custom message', async () => { | ||
await expect(timeout(delay(105), 100, 'custom error')).rejects.toThrowError('custom error') | ||
}) | ||
}) |