import { assertMethodDecorator } from "../common/decorators.js"; import type { AsyncMethod } from "../common/types.js"; import { TimeoutError } from "./timeout-error.js"; export function createTimedMethod( originalMethod: AsyncMethod, ms: number, ): AsyncMethod { return async function(this: This, ...args: Args): Promise { let timeoutId: ReturnType | undefined; try { return await Promise.race([ originalMethod.apply(this, args), new Promise((_resolve, reject) => { timeoutId = setTimeout(() => { reject(new TimeoutError(ms)); }, ms); }), ]); } finally { if (timeoutId !== undefined) { clearTimeout(timeoutId); } } }; } export function timeout(ms: number) { return function( value: AsyncMethod, context: ClassMethodDecoratorContext>, ): AsyncMethod { assertMethodDecorator("timeout", value, context); return createTimedMethod(value, ms); }; }