import * as E from "fp-ts/lib/Either"; import * as TE from "fp-ts/lib/TaskEither"; export function promiseWithTimeout( timeoutMs: number, promise: () => Promise ): Promise { let timeoutHandle: NodeJS.Timeout; const timeoutPromise = new Promise((_resolve, reject) => { timeoutHandle = setTimeout( () => reject(new Error("Promise timed out")), timeoutMs ); }); return Promise.race([promise(), timeoutPromise]).then((result) => { clearTimeout(timeoutHandle); return result; }); } type ResultPromise = | { readonly _tag: "Timeout"; } | E.Either; export function taskEitherWithTimeout( timeoutMs: number ): (callback: TE.TaskEither) => TE.TaskEither { return function (callback: TE.TaskEither) { return async function () { let timeoutHandle: NodeJS.Timeout; const timeoutPromise = new Promise>((resolve) => { timeoutHandle = setTimeout( () => resolve({ _tag: "Timeout" }), timeoutMs ); }); return Promise.race([callback(), timeoutPromise]).then((result) => { clearTimeout(timeoutHandle); switch (result._tag) { case "Timeout": return E.left(new Error("Promise timed out")); case "Left": return E.left(E.toError(result)); case "Right": return E.right(result.right); } }); }; }; }