72 lines
1.9 KiB
JavaScript
Raw Normal View History

2025-11-11 01:05:13 +01:00
export function debounce(fn, delay = 300) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), delay);
};
}
export function throttle(fn, delay = 300) {
let lastCall = 0;
let timeoutId;
return function (...args) {
const now = Date.now();
if (now - lastCall >= delay) {
lastCall = now;
fn.apply(this, args);
} else {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
lastCall = Date.now();
fn.apply(this, args);
}, delay - (now - lastCall));
}
};
}
export function once(fn) {
let called = false;
return function (...args) {
if (!called) {
called = true;
return fn.apply(this, args);
}
};
}
export function compose(...fns) {
return (value) => fns.reduceRight((acc, fn) => fn(acc), value);
}
export function pipe(...fns) {
return (value) => fns.reduce((acc, fn) => fn(acc), value);
}
export async function retry(fn, maxAttempts = 3, delay = 1000) {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (error) {
if (attempt === maxAttempts) throw error;
await new Promise(resolve => setTimeout(resolve, delay * attempt));
}
}
}
export function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj;
if (obj instanceof Date) return new Date(obj.getTime());
if (obj instanceof Array) return obj.map(item => deepClone(item));
if (obj instanceof Object) {
const cloned = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
cloned[key] = deepClone(obj[key]);
}
}
return cloned;
}
}