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
JavaScript
/**
* 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,
};