UNPKG

besper-frontend-site-dev-0935

Version:

Professional B-esper Frontend Site - Site-wide integration toolkit for full website bot deployment

287 lines (262 loc) 8.53 kB
/** * Global Function Safety Utility * Provides safe wrappers and fallbacks for global functions that may not be immediately available * Prevents "undefined function" errors during page load timing issues */ /** * Safe wrapper for besperAutoPageIntegration function * Waits for function to be available or provides helpful error message * @param {Object} config - Configuration object for page integration * @param {number} timeout - Maximum time to wait in milliseconds (default: 5000) * @returns {Promise<boolean>} Success status */ export async function safePageIntegration(config = {}, timeout = 5000) { const startTime = Date.now(); // Function to check if besperAutoPageIntegration is available const checkFunction = () => { return typeof window.besperAutoPageIntegration === 'function'; }; // If function is already available, use it immediately if (checkFunction()) { console.log( '[SafeIntegration] [SUCCESS] besperAutoPageIntegration available immediately' ); try { return await window.besperAutoPageIntegration(config); } catch (error) { console.error( '[SafeIntegration] [ERROR] Error in besperAutoPageIntegration:', error ); return false; } } // Wait for function to become available console.log( '[SafeIntegration] ⏳ Waiting for besperAutoPageIntegration to load...' ); return new Promise(resolve => { const checkInterval = 100; // Check every 100ms let elapsed = 0; const intervalId = setInterval(async () => { elapsed = Date.now() - startTime; if (checkFunction()) { clearInterval(intervalId); console.log( `[SafeIntegration] [SUCCESS] besperAutoPageIntegration loaded after ${elapsed}ms` ); try { const result = await window.besperAutoPageIntegration(config); resolve(result); } catch (error) { console.error( '[SafeIntegration] [ERROR] Error in besperAutoPageIntegration:', error ); resolve(false); } return; } if (elapsed >= timeout) { clearInterval(intervalId); console.error( `[SafeIntegration] [WARN] besperAutoPageIntegration not available after ${timeout}ms` ); // Show user-friendly error showIntegrationError( config, 'besperAutoPageIntegration function not loaded' ); resolve(false); } }, checkInterval); }); } /** * Safe wrapper for pageOperatorsService functions * Provides fallbacks when service is not available * @param {string} operationName - Name of the operation to call * @param {...any} args - Arguments to pass to the operation * @returns {Promise<any>} Operation result or fallback */ export async function safeOperatorCall(operationName, ...args) { // Check if pageOperatorsService is available if ( typeof window !== 'undefined' && window.pageOperatorsService && typeof window.pageOperatorsService[operationName] === 'function' ) { try { console.log( `[SafeOperators] 🔧 Calling ${operationName} with args:`, args ); const result = await window.pageOperatorsService[operationName](...args); console.log( `[SafeOperators] [SUCCESS] ${operationName} completed successfully` ); return result; } catch (error) { console.error( `[SafeOperators] [ERROR] Error in ${operationName}:`, error ); return getFallbackResult(operationName, error); } } // Service not available - provide fallback console.warn( `[SafeOperators] [WARN] pageOperatorsService.${operationName} not available` ); return getFallbackResult(operationName, new Error('Service not available')); } /** * Specific safe wrapper for getSupportTickets * @param {Object} options - Options for getting support tickets * @returns {Promise<Object>} Support tickets result or fallback */ export async function safeGetSupportTickets(options = {}) { return await safeOperatorCall('getSupportTickets', options); } /** * Get fallback result for operations * @param {string} operationName - Name of the operation * @param {Error} error - The error that occurred * @returns {Object} Fallback result */ function getFallbackResult(operationName, error) { console.log( `[SafeOperators] [LOADING] Providing fallback for ${operationName}` ); const fallbacks = { getSupportTickets: { success: false, data: [], error: error.message, fallback: true, message: 'Support tickets service is currently unavailable. Please refresh the page or try again later.', }, getSupportTicket: { success: false, data: null, error: error.message, fallback: true, message: 'Support ticket details are currently unavailable.', }, getNotifications: { success: false, data: [], error: error.message, fallback: true, message: 'Notifications service is currently unavailable.', }, }; return ( fallbacks[operationName] || { success: false, error: error.message, fallback: true, message: `${operationName} service is currently unavailable.`, } ); } /** * Show user-friendly error message when integration fails * @param {Object} config - Original configuration * @param {string} errorMessage - Error message to display */ function showIntegrationError(config, errorMessage) { const container = document.getElementById('besper-site-container') || document.querySelector('[id*="besper"]') || document.body; if (container) { container.innerHTML = ` <div style=" padding: 20px; margin: 20px; background: #fff3cd; border: 1px solid #ffeb3b; border-radius: 8px; color: #856404; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; "> <div style="font-weight: 600; margin-bottom: 8px;"> [WARN] Page Loading Issue </div> <div style="margin-bottom: 12px;"> The page integration script is taking longer than expected to load. </div> <div style="font-size: 14px; color: #6c757d;"> ${errorMessage} </div> <button onclick="location.reload()" style=" margin-top: 12px; padding: 8px 16px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; "> [LOADING] Refresh Page </button> </div> `; } } /** * Initialize safe global function wrappers * Call this early in page load to set up safe wrappers */ export function initializeSafeGlobals() { if (typeof window === 'undefined') return; // Create safe wrapper for besperAutoPageIntegration if it doesn't exist if (!window.besperAutoPageIntegration) { window.besperAutoPageIntegration = async config => { console.log( '[SafeGlobals] [LOADING] Using safe wrapper for besperAutoPageIntegration' ); return await safePageIntegration(config); }; } // Ensure pageOperatorsService has safe methods if (!window.pageOperatorsService) { window.pageOperatorsService = { getSupportTickets: async options => { console.log( '[SafeGlobals] [LOADING] Using safe wrapper for getSupportTickets' ); return await safeGetSupportTickets(options); }, }; } else if ( window.pageOperatorsService && !window.pageOperatorsService.getSupportTickets ) { // If pageOperatorsService exists but getSupportTickets is missing, add it window.pageOperatorsService.getSupportTickets = async options => { console.log( '[SafeGlobals] [LOADING] Adding missing getSupportTickets to existing pageOperatorsService' ); return await safeGetSupportTickets(options); }; } console.log('[SafeGlobals] 🛡️ Safe global function wrappers initialized'); } // Auto-initialize if in browser environment if (typeof window !== 'undefined') { // Initialize immediately if DOM is ready, otherwise wait if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initializeSafeGlobals); } else { initializeSafeGlobals(); } } export default { safePageIntegration, safeOperatorCall, safeGetSupportTickets, initializeSafeGlobals, };