From e426ce516eb8fec3055caa06729230741cca537c Mon Sep 17 00:00:00 2001 From: Martin Karkowski Date: Fri, 17 Sep 2021 09:14:55 +0200 Subject: [PATCH] Fixing Browser and adding waitfor --- lib/helpers/async.ts | 157 ++++++++++++++++++++++++++++++++++++ lib/logger/index.browser.ts | 1 + 2 files changed, 158 insertions(+) diff --git a/lib/helpers/async.ts b/lib/helpers/async.ts index d3e86cc..b4acbe4 100644 --- a/lib/helpers/async.ts +++ b/lib/helpers/async.ts @@ -18,3 +18,160 @@ export function sleep(delay: number): Promise { export function isAsyncFunction(func: (...args) => any): boolean { return func.constructor.name === "AsyncFunction"; } + + +/** + * Function which will halt the Process until the Testcallback deliveres "true" + * + * @export + * @param {(() => boolean | Promise)} testCallback Function which is used to periodically test the State + * @param {{ testFirst?: boolean; maxRetries?: number, timeout?: number, maxTimeout?: number }} [options={}] Options to enhance the + * @returns + */ +export function waitFor(testCallback: () => boolean | Promise, options: { initialWait?: number, testFirst?: boolean; maxRetries?: number, timeout?: number, maxTimeout?: number, additionalDelay?: number } = {}): Promise { + + const _options = Object.assign({ + testFirst: true, + timeout: 50 + }, options); + + const _isAsync = isAsyncFunction(testCallback); + + if (_isAsync) { + return new Promise(async (resolve, reject) => { + if (options.initialWait) { + await sleep(options.initialWait); + } + + let _resolve: () => void; + if (_options.additionalDelay) { + _resolve = () => setTimeout(resolve, _options.additionalDelay); + } else { + _resolve = resolve; + } + + try { + if (_options.testFirst && await testCallback()) { + _resolve(); + } else { + let retryCounter = 0; + + + let timeout: any | null = null; + let interval: any | null = null; + + // If there is a Timeout, define a Timeout Function, which will + // Throw an Error on Timeout. + if (_options.maxTimeout) { + timeout = setTimeout(async () => { + + if (interval) { + clearInterval(interval); + } + + reject(new Error("Wait has been Timeout")); + }, _options.maxTimeout); + } + + // Define a Testfunction, which will periodically test whether the condition is + // fullfield or not. Internally it counts the number of retries, if the max allowed + // number of retries has been reached => Throw an Error + interval = setInterval(async () => { + try { + if (_options.maxRetries && retryCounter > _options.maxRetries) { + reject(new RangeError("Max Retries has been reached")); + } else if (await testCallback()) { + + // Clear out the Interval + clearInterval(interval); + + // If there is a Timeout clear it as well; + if (timeout) { + clearTimeout(timeout); + } + + _resolve(); + } + retryCounter += 1; + } catch (err) { + reject(err); + } + }); + } + } catch (e) { + reject(e); + } + }); + } else { + return new Promise((resolve, reject) => { + const _func = () => { + let _resolve: () => void; + if (_options.additionalDelay) { + _resolve = () => setTimeout(resolve, _options.additionalDelay); + } else { + _resolve = resolve; + } + + try { + if (_options.testFirst && testCallback()) { + if (_options.additionalDelay) { + setTimeout(resolve, _options.additionalDelay); + } else { + _resolve(); + } + } else { + let retryCounter = 0; + + let timeout: any | null = null; + let interval: any | null = null; + + // If there is a Timeout, define a Timeout Function, which will + // Throw an Error on Timeout. + if (_options.maxTimeout) { + timeout = setTimeout(async () => { + + if (interval) { + clearInterval(interval); + } + + reject(new Error("Wait has been Timeout")); + }, _options.maxTimeout); + } + + // Define a Testfunction, which will periodically test whether the condition is + // fullfield or not. Internally it counts the number of retries, if the max allowed + // number of retries has been reached => Throw an Error + interval = setInterval(() => { + try { + if (_options.maxRetries && retryCounter > _options.maxRetries) { + reject(new RangeError("Max Retries has been reached")); + } else if (testCallback()) { + + // Clear out the Interval + clearInterval(interval); + + // If there is a Timeout clear it as well; + if (timeout) { + clearTimeout(timeout); + } + + _resolve(); + } + retryCounter += 1; + } catch (err) { + reject(err); + } + }); + } + } catch (e) { + reject(e); + } + }; + if (options.initialWait) { + setTimeout(_func, options.initialWait); + } else { + _func(); + } + }); + } +} \ No newline at end of file diff --git a/lib/logger/index.browser.ts b/lib/logger/index.browser.ts index c0a1112..a54801c 100644 --- a/lib/logger/index.browser.ts +++ b/lib/logger/index.browser.ts @@ -6,6 +6,7 @@ * @desc [description] */ +export { ILogger } from "js-logger"; export { getLogerAsEventEmitter, TCallback, TCallbackWithLevel, useEventLogger } from "./eventLogging"; export { getCentralNopeLogger, getNopeLogger } from "./getLogger"; export { LoggerLevel, LoggerLevels } from "./nopeLogger";