@nasriya/atomix
Version:
Composable helper functions for building reliable systems
205 lines (204 loc) • 7.64 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
class CommonUtils {
/**
* Generate a random text
* @param length The length of the text. Minimum of `4`
* @param [options] Options for generating the text
* @returns The generated text
* @since v1.0.0
*/
generateRandom(length, options = {}) {
const { includeNumbers = true, includeLetters = true, includeSymbols = true, includeLowerCaseChars = true, includeUpperCaseChars = true, beginWithLetter = true, noSimilarChars = true, noDuplicateChars = false, noSequentialChars = true } = options;
let chars = '';
let text = '';
if (includeNumbers)
chars += '0123456789';
if (includeLetters) {
if (includeLowerCaseChars)
chars += 'abcdefghijklmnopqrstuvwxyz';
if (includeUpperCaseChars)
chars += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
}
if (includeSymbols)
chars += '!";#$%&\'()*+,-./:;<=>?@[]^_`{|}~';
if (beginWithLetter && (includeLetters || includeNumbers || includeSymbols)) {
const validChars = includeLetters && includeNumbers && includeSymbols ? chars : chars.slice(10);
text += validChars.charAt(Math.floor(Math.random() * validChars.length));
}
while (text.length < length) {
const randomIndex = Math.floor(Math.random() * chars.length);
const char = chars[randomIndex];
if ((noSimilarChars && /[il1LoO]/.test(char)) ||
(noDuplicateChars && text.includes(char)) ||
(noSequentialChars && text.length > 0 && text[text.length - 1].charCodeAt(0) + 1 === char.charCodeAt(0))) {
continue;
}
text += char;
}
return text;
}
/**
* Pauses execution for a specified number of milliseconds.
*
* This function returns a promise that resolves after the given duration,
* allowing for asynchronous code to wait before proceeding.
*
* @param ms - The number of milliseconds to sleep.
* @returns A promise that resolves after the specified delay.
* @since v1.0.0
*/
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
/**
* Debounces a function, delaying its invocation until the specified delay
* period has passed since the last call.
*
* The debounced function returns a promise that resolves with the result
* of the original function. If the debounced function is called again
* before the delay period has passed, the previous promise is rejected
* with an error and a new promise is returned.
*
* The debounced function also has a `cancel` method that can be called to
* cancel the current pending invocation. If called, the promise is rejected
* with an error and the timer is cleared.
*
* @param fn - The function to debounce.
* @param delay - The number of milliseconds to delay the invocation of the function.
* @returns A debounced version of the given function.
* @since v1.0.0
*/
debounce(fn, delay) {
let timeout = null;
let resolveFn = null;
let rejectFn = null;
const debounced = (...args) => {
if (timeout)
clearTimeout(timeout);
return new Promise((resolve, reject) => {
resolveFn = resolve;
rejectFn = reject;
timeout = setTimeout(async () => {
try {
const result = await fn(...args);
resolveFn?.(result);
}
catch (error) {
rejectFn?.(error);
}
}, delay);
});
};
debounced.cancel = () => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
// Reject the pending Promise if any
rejectFn?.(new Error('Debounced function cancelled'));
resolveFn = null;
rejectFn = null;
}
};
return debounced;
}
/**
* Returns a debounced version of the given function that does not return a promise.
*
* When the given function is called, it will wait the specified delay before
* actually calling the function. If the function is called multiple times
* within that delay, it will only call the function once after the delay
* has passed.
*
* @param fn - The function to debounce.
* @param delay - The number of milliseconds to delay calling the function.
* @returns A debounced version of the given function.
* @since v1.0.8
*/
debounceSync(fn, delay, options) {
let timeout = null;
const debounced = (...args) => {
if (timeout)
clearTimeout(timeout);
timeout = setTimeout(() => {
try {
const result = fn(...args);
options?.onDone?.(result);
}
catch (error) {
options?.onError?.(error);
}
}, delay);
};
debounced.cancel = () => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
};
return debounced;
}
/**
* Returns a throttled version of the given function.
*
* The throttled function will only invoke the original function at most
* once in the specified delay period. If the function returns a promise,
* it will maintain the promise chain and resolve with the promise's value.
* If the throttled function is called again before the delay has passed,
* it will return the pending promise or resolve immediately if there is none.
*
* @param fn - The function to throttle.
* @param delay - The number of milliseconds to throttle invocations to.
* @returns A throttled version of the given function that returns a promise.
* @since v1.0.0
*/
throttle(fn, delay) {
let lastTime = 0;
let pendingPromise = null;
return (...args) => {
const now = Date.now();
if (now - lastTime < delay) {
return pendingPromise || Promise.resolve();
}
lastTime = now;
const result = fn(...args);
if (result instanceof Promise) {
pendingPromise = result.then((val) => {
pendingPromise = null;
return val;
});
return pendingPromise;
}
else {
return Promise.resolve(result);
}
};
}
/**
* A no-operation function useful as a placeholder callback.
* @since v1.0.0
*/
noop() { }
/**
* Wraps a function such that it will only be called once.
*
* All subsequent calls will return the cached result of the first call.
*
* @param fn - The function to wrap.
* @returns A wrapped version of the function that will only be called once.
* @since v1.0.0
*/
once(fn) {
let called = false;
let result;
return (...args) => {
if (!called) {
called = true;
result = fn(...args);
}
return result;
};
}
}
const commonUtils = new CommonUtils();
exports.default = commonUtils;