UNPKG

frontend-hamroun

Version:

A lightweight frontend JavaScript framework with React-like syntax

144 lines (143 loc) 4.54 kB
/** * Common utility functions for the framework */ /** * Creates a debounced function that delays invoking the provided function * until after the specified wait time has elapsed since the last time it was invoked. */ export function debounce(func, wait) { let timeout = null; const debounced = function (...args) { const later = () => { timeout = null; func.apply(this, args); }; if (timeout !== null) { clearTimeout(timeout); } timeout = setTimeout(later, wait); }; debounced.cancel = function () { if (timeout !== null) { clearTimeout(timeout); timeout = null; } }; return debounced; } /** * Creates a throttled function that only invokes the provided function * at most once per every wait milliseconds. */ export function throttle(func, wait) { let timeout = null; let previous = 0; const throttled = function (...args) { const now = Date.now(); const remaining = wait - (now - previous); if (remaining <= 0 || remaining > wait) { if (timeout !== null) { clearTimeout(timeout); timeout = null; } previous = now; func.apply(this, args); } else if (timeout === null) { timeout = setTimeout(() => { previous = Date.now(); timeout = null; func.apply(this, args); }, remaining); } }; throttled.cancel = function () { if (timeout !== null) { clearTimeout(timeout); timeout = null; } previous = 0; }; return throttled; } /** * Deep clones an object by using JSON serialization */ export function deepClone(obj) { if (obj === null || typeof obj !== 'object') { return obj; } return JSON.parse(JSON.stringify(obj)); } /** * Creates a memoized version of a function that caches results based on arguments */ export function memoize(func) { const cache = new Map(); return ((...args) => { const key = JSON.stringify(args); if (cache.has(key)) { return cache.get(key); } const result = func(...args); cache.set(key, result); return result; }); } /** * Creates a UUID v4 string */ export function uuid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { const r = Math.random() * 16 | 0; const v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } /** * Formats a date according to the specified format */ export function formatDate(date, format) { const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; const shortMonths = months.map(m => m.slice(0, 3)); const days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ]; const shortDays = days.map(d => d.slice(0, 3)); const tokens = { 'YYYY': () => date.getFullYear().toString(), 'YY': () => (date.getFullYear() % 100).toString().padStart(2, '0'), 'MMMM': () => months[date.getMonth()], 'MMM': () => shortMonths[date.getMonth()], 'MM': () => (date.getMonth() + 1).toString().padStart(2, '0'), 'M': () => (date.getMonth() + 1).toString(), 'DDDD': () => days[date.getDay()], 'DDD': () => shortDays[date.getDay()], 'DD': () => date.getDate().toString().padStart(2, '0'), 'D': () => date.getDate().toString(), 'HH': () => date.getHours().toString().padStart(2, '0'), 'H': () => date.getHours().toString(), 'hh': () => (date.getHours() % 12 || 12).toString().padStart(2, '0'), 'h': () => (date.getHours() % 12 || 12).toString(), 'mm': () => date.getMinutes().toString().padStart(2, '0'), 'm': () => date.getMinutes().toString(), 'ss': () => date.getSeconds().toString().padStart(2, '0'), 's': () => date.getSeconds().toString(), 'a': () => date.getHours() < 12 ? 'am' : 'pm', 'A': () => date.getHours() < 12 ? 'AM' : 'PM' }; const tokenRegex = new RegExp(Object.keys(tokens).join('|'), 'g'); return format.replace(tokenRegex, (match) => tokens[match]()); } export default { debounce, throttle, deepClone, memoize, uuid, formatDate };