UNPKG

@funnelenvy-npm/fe-dev-utils

Version:

Helper function to build client side A/B tests

80 lines (79 loc) 3.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const get_element_1 = __importDefault(require("../get-element")); const on_error_1 = __importDefault(require("../on-error")); /** * Poller function that waits for a set of conditions to be true before executing a callback function. * * @param options - Options object to configure the function. * @throws {TypeError} - If `conditions` is not an array, `callback` is not a function, * or `timeout` and `pollFreq` are not numbers greater than or equal to 1000 and 10, respectively. */ const waitForConditions = ({ conditions, callback, activity = null, errorHandler = null, timeout = 10000, pollFreq = 100, }) => { if (!Array.isArray(conditions)) { throw new TypeError('The first parameter must be an array'); } if (typeof callback !== 'function') { throw new TypeError('The second parameter must be a function'); } if (typeof timeout !== 'number' || timeout < 1000) { throw new TypeError('The third parameter must be a number greater than or equal to 1000'); } const promises = conditions.map((condition) => { if (typeof condition === 'function') { return new Promise((resolve, reject) => { let intervalId; let timeoutId; const clearIds = () => { clearInterval(intervalId); clearTimeout(timeoutId); }; intervalId = setInterval(() => { try { if (condition()) { clearIds(); resolve(true); } } catch (err) { clearIds(); reject(new Error(`Error executing condition function: ${err}`)); } }, pollFreq); timeoutId = setTimeout(() => { clearIds(); reject(new Error(`Condition function timed out: ${condition.toString()}`)); }, timeout); }); } return (0, get_element_1.default)({ condition, activity: activity ?? undefined, errorHandler: () => null }); }); Promise.all(promises) .then((results) => { // Build an object of elements from string conditions. // Note: Function conditions resolve to a boolean and aren’t included. const elements = conditions.reduce((acc, cond, index) => { if (typeof cond === 'string') { const result = results[index]; if (result && typeof result.selector === 'string') { acc[result.selector] = result.elements; } } return acc; }, {}); // Now that all promises have resolved, fire the callback. callback(elements); }) .catch((error) => { if (errorHandler && typeof errorHandler === 'function') { errorHandler({ activity, error }); } else { (0, on_error_1.default)({ activity: activity ?? undefined, error }); } }); }; exports.default = waitForConditions;