UNPKG

aura-glass

Version:

A comprehensive glassmorphism design system for React applications with 142+ production-ready components

460 lines (457 loc) 13.2 kB
import { detectDevice } from './deviceCapabilities.js'; /** * Production utilities for AuraGlass components * These utilities are optimized for production environments */ // === Environment Detection === const isProduction = () => { return process.env.NODE_ENV === 'production'; }; const isDevelopment = () => { return process.env.NODE_ENV === 'development'; }; // === Logging Utilities === const logger = { error: (message, ...args) => { if (isDevelopment()) { console.error(`[AuraGlass Error]: ${message}`, ...args); } }, warn: (message, ...args) => { if (isDevelopment()) { console.warn(`[AuraGlass Warning]: ${message}`, ...args); } }, info: (message, ...args) => { if (isDevelopment()) { console.info(`[AuraGlass Info]: ${message}`, ...args); } }, debug: (message, ...args) => { if (isDevelopment()) { console.debug(`[AuraGlass Debug]: ${message}`, ...args); } } }; // === Performance Utilities === const performance = { measure: (name, fn) => { if (!isDevelopment()) { fn(); return 0; } const start = Date.now(); fn(); const end = Date.now(); const duration = end - start; logger.debug(`Performance: ${name} took ${duration}ms`); return duration; }, measureAsync: async (name, fn) => { if (!isDevelopment()) { await fn(); return 0; } const start = Date.now(); await fn(); const end = Date.now(); const duration = end - start; logger.debug(`Performance: ${name} took ${duration}ms`); return duration; } }; // === Error Handling === const safeExecute = (fn, fallback, errorMessage) => { try { return fn(); } catch (error) { logger.error(errorMessage || 'Safe execution failed', error); return fallback; } }; const safeExecuteAsync = async (fn, fallback, errorMessage) => { try { return await fn(); } catch (error) { logger.error(errorMessage || 'Safe async execution failed', error); return fallback; } }; // === Feature Detection === const features = { supportsIntersectionObserver: () => { return typeof IntersectionObserver !== 'undefined'; }, supportsResizeObserver: () => { return typeof ResizeObserver !== 'undefined'; }, supportsBackdropFilter: () => { if (typeof CSS === 'undefined') return false; return CSS.supports('backdrop-filter', 'blur(1px)') || CSS.supports('-webkit-backdrop-filter', 'blur(1px)'); }, supportsWebGL: () => { if (typeof window === 'undefined') return false; // Use cached device detection to avoid creating contexts repeatedly return detectDevice().capabilities.webgl; }, supportsWebP: () => { if (typeof CSS === 'undefined') return false; return CSS.supports('image-format', 'webp'); }, supportsAVIF: () => { if (typeof CSS === 'undefined') return false; return CSS.supports('image-format', 'avif'); }, supportsContainerQueries: () => { if (typeof CSS === 'undefined') return false; return CSS.supports('container-type', 'inline-size'); } }; // === Memory Management === const memory = { cleanup: refs => { refs.forEach(ref => { if (ref.current) { ref.current = null; } }); }, debounce: (func, wait) => { let timeout; return (...args) => { clearTimeout(timeout); timeout = setTimeout(() => func.apply(null, args), wait); }; }, throttle: (func, limit) => { let inThrottle; return (...args) => { if (!inThrottle) { func.apply(null, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } }; // === Validation === const validate = { isValidHexColor: color => { return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color); }, isValidRgbaColor: color => { return /^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(,\s*[\d.]+)?\s*\)$/.test(color); }, isValidCSSUnit: value => { return /^-?\d+(\.\d+)?(px|em|rem|%|vh|vw|vmin|vmax|ch|ex)$/.test(value); }, isValidEmail: email => { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); }, isValidUrl: url => { try { new URL(url); return true; } catch { return false; } } }; // === Data Utilities === const data = { generateId: (prefix = 'glass') => { return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; }, 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(data.deepClone); if (typeof obj === 'object') { const cloned = {}; for (const key in obj) { cloned[key] = data.deepClone(obj[key]); } return cloned; } return obj; }, isEqual: (a, b) => { if (a === b) return true; if (a == null || b == null) return false; if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) return false; return a.every((val, index) => data.isEqual(val, b[index])); } if (typeof a === 'object' && typeof b === 'object') { const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; return keysA.every(key => data.isEqual(a[key], b[key])); } return false; }, omit: (obj, keys) => { const result = { ...obj }; keys.forEach(key => delete result[key]); return result; }, pick: (obj, keys) => { const result = {}; keys.forEach(key => { if (key in obj) { result[key] = obj[key]; } }); return result; } }; // === CSS Utilities === const css = { classNames: (...classes) => { return classes.filter(Boolean).join(' '); }, mergeStyles: (...styles) => { return styles.filter(style => style !== undefined).reduce((merged, style) => ({ ...merged, ...style }), {}); }, pxToRem: (px, baseFontSize = 16) => { return `${px / baseFontSize}rem`; }, hexToRgba: (hex, alpha) => { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); const b = parseInt(hex.slice(5, 7), 16); return `rgba(${r}, ${g}, ${b}, ${alpha})`; } }; // === Browser Utilities === const browser = { isChrome: () => { return /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); }, isFirefox: () => { return /Firefox/.test(navigator.userAgent); }, isSafari: () => { return /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent); }, isEdge: () => { return /Edg/.test(navigator.userAgent); }, isMobile: () => { return /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); }, isTouch: () => { return 'ontouchstart' in window || navigator.maxTouchPoints > 0; }, getViewportSize: () => { return { width: window.innerWidth, height: window.innerHeight }; }, getDevicePixelRatio: () => { return window.devicePixelRatio || 1; } }; // === Storage Utilities === const storage = { set: (key, value) => { safeExecute(() => { localStorage.setItem(key, JSON.stringify(value)); }, undefined, `Failed to save to localStorage: ${key}`); }, get: (key, fallback) => { return safeExecute(() => { const item = localStorage.getItem(key); return item ? JSON.parse(item) : fallback; }, fallback, `Failed to read from localStorage: ${key}`); }, remove: key => { safeExecute(() => { localStorage.removeItem(key); }, undefined, `Failed to remove from localStorage: ${key}`); }, clear: () => { safeExecute(() => { localStorage.clear(); }, undefined, 'Failed to clear localStorage'); } }; // === Analytics Utilities === const analytics = { track: (event, properties) => { if (isProduction()) { // Integration point for analytics service // Example: analyticsService.track(event, properties); safeExecute(() => { // Your analytics implementation here if (isDevelopment()) { logger.debug(`Analytics: ${event}`, properties); } }, undefined, `Failed to track analytics event: ${event}`); } }, page: (page, properties) => { if (isProduction()) { // Integration point for page tracking // Example: analyticsService.page(page, properties); safeExecute(() => { // Your page tracking implementation here if (isDevelopment()) { logger.debug(`Page: ${page}`, properties); } }, undefined, `Failed to track page view: ${page}`); } }, identify: (userId, traits) => { if (isProduction()) { // Integration point for user identification // Example: analyticsService.identify(userId, traits); safeExecute(() => { // Your user identification implementation here if (isDevelopment()) { logger.debug(`Identify: ${userId}`, traits); } }, undefined, `Failed to identify user: ${userId}`); } } }; // === Production Configuration === const productionConfig = { // Error reporting configuration errorReporting: { enabled: isProduction(), endpoint: process.env.REACT_APP_ERROR_ENDPOINT || '', apiKey: process.env.REACT_APP_ERROR_API_KEY || '', maxRetries: 3, retryDelay: 1000 }, // Analytics configuration analytics: { enabled: isProduction(), trackingId: process.env.REACT_APP_ANALYTICS_ID || '', sampleRate: 1.0, enableAutoPageTracking: true }, // Performance configuration performance: { enableMonitoring: isProduction(), sampleRate: 0.1, // Monitor 10% of sessions thresholds: { renderTime: 16, // 60fps memoryUsage: 0.8, // 80% of available memory bundleSize: 150 * 1024 // 150KB } }, // Feature flags features: { enableAdvancedAnimations: true, enableVirtualization: true, enableLazyLoading: true, enableA11yAuditing: isDevelopment(), enablePerformanceMonitoring: true } }; // === Health Checks === const health = { checkGlassSupport: () => { const issues = []; if (!features.supportsBackdropFilter()) { issues.push('Backdrop filter not supported'); } if (!features.supportsIntersectionObserver()) { issues.push('Intersection Observer not supported'); } if (!features.supportsResizeObserver()) { issues.push('Resize Observer not supported'); } return { supported: issues.length === 0, issues }; }, checkPerformance: () => { const recommendations = []; let score = 100; // Check device capabilities if (!features.supportsWebGL()) { score -= 20; recommendations.push('Enable GPU acceleration for better performance'); } if (browser.isMobile()) { score -= 10; recommendations.push('Consider reduced effects for mobile devices'); } // Check memory const memory = performance.memory; if (memory && memory.usedJSHeapSize / memory.jsHeapSizeLimit > 0.8) { score -= 30; recommendations.push('High memory usage detected - enable virtualization'); } return { score, recommendations }; } }; // === Production Initialization === const initializeProduction = () => { if (!isProduction()) return; // Set up error handling window.addEventListener('error', event => { logger.error('Unhandled error:', event.error); }); window.addEventListener('unhandledrejection', event => { logger.error('Unhandled promise rejection:', event.reason); }); // Check glass support const glassSupport = health.checkGlassSupport(); if (!glassSupport.supported) { logger.warn('Glass effects may not work properly:', glassSupport.issues); } // Check performance const performanceCheck = health.checkPerformance(); if (performanceCheck.score < 70) { logger.warn('Performance issues detected:', performanceCheck.recommendations); } logger.info('AuraGlass production mode initialized'); }; // === Development Helpers === const dev = { logComponentRender: (componentName, props) => { if (isDevelopment()) { logger.debug(`Render: ${componentName}`, props); } }, logPerformanceWarning: (componentName, metric, value, threshold) => { if (isDevelopment() && value > threshold) { logger.warn(`Performance: ${componentName} ${metric} (${value}) exceeds threshold (${threshold})`); } }, validateProps: (props, schema) => { if (!isDevelopment()) return true; const errors = []; Object.entries(schema).forEach(([key, validator]) => { const value = props[key]; const validatorFn = validator; if (value !== undefined && !validatorFn(value)) { errors.push(`Invalid prop: ${key}`); } }); if (errors.length > 0) { logger.error('Prop validation failed:', errors); return false; } return true; } }; export { analytics, browser, css, data, dev, features, health, initializeProduction, isDevelopment, isProduction, logger, memory, performance, productionConfig, safeExecute, safeExecuteAsync, storage, validate }; //# sourceMappingURL=productionUtils.js.map