Fix mobile Safari reload loop by persisting config cache in window object
All checks were successful
Build And Push Image / docker (push) Successful in 2m56s
All checks were successful
Build And Push Image / docker (push) Successful in 2m56s
- Store config cache in window.__configCache instead of module-level variable to maintain persistence across Vue reactivity cycles - Fix cardClasses ref to store computed value instead of function - Add client plugin for config cache initialization - Add documentation for mobile Safari reload loop fix
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
|
||||
import type { RecaptchaConfig, RegistrationConfig } from './types';
|
||||
|
||||
// Global cache storage
|
||||
// Global cache storage - use window object to persist across Vue reactivity cycles
|
||||
interface ConfigCache {
|
||||
recaptcha: RecaptchaConfig | null;
|
||||
registration: RegistrationConfig | null;
|
||||
@@ -16,14 +16,32 @@ interface ConfigCache {
|
||||
registrationError: string | null;
|
||||
}
|
||||
|
||||
let globalConfigCache: ConfigCache = {
|
||||
recaptcha: null,
|
||||
registration: null,
|
||||
recaptchaLoading: false,
|
||||
registrationLoading: false,
|
||||
recaptchaError: null,
|
||||
registrationError: null
|
||||
};
|
||||
// Use window object for true persistence across component lifecycle
|
||||
function getGlobalCache(): ConfigCache {
|
||||
if (typeof window === 'undefined') {
|
||||
return {
|
||||
recaptcha: null,
|
||||
registration: null,
|
||||
recaptchaLoading: false,
|
||||
registrationLoading: false,
|
||||
recaptchaError: null,
|
||||
registrationError: null
|
||||
};
|
||||
}
|
||||
|
||||
if (!(window as any).__configCache) {
|
||||
(window as any).__configCache = {
|
||||
recaptcha: null,
|
||||
registration: null,
|
||||
recaptchaLoading: false,
|
||||
registrationLoading: false,
|
||||
recaptchaError: null,
|
||||
registrationError: null
|
||||
};
|
||||
}
|
||||
|
||||
return (window as any).__configCache;
|
||||
}
|
||||
|
||||
// Circuit breaker to prevent rapid successive calls
|
||||
const CIRCUIT_BREAKER_THRESHOLD = 5; // Max calls in time window
|
||||
@@ -55,8 +73,11 @@ function shouldBlockCall(apiName: string): boolean {
|
||||
* Get reCAPTCHA configuration with caching and circuit breaker
|
||||
*/
|
||||
export async function getCachedRecaptchaConfig(): Promise<RecaptchaConfig> {
|
||||
const globalConfigCache = getGlobalCache();
|
||||
|
||||
// Return cached result if available
|
||||
if (globalConfigCache.recaptcha) {
|
||||
console.log('[config-cache] Returning cached reCAPTCHA config');
|
||||
return globalConfigCache.recaptcha;
|
||||
}
|
||||
|
||||
@@ -125,8 +146,11 @@ export async function getCachedRecaptchaConfig(): Promise<RecaptchaConfig> {
|
||||
* Get registration configuration with caching and circuit breaker
|
||||
*/
|
||||
export async function getCachedRegistrationConfig(): Promise<RegistrationConfig> {
|
||||
const globalConfigCache = getGlobalCache();
|
||||
|
||||
// Return cached result if available
|
||||
if (globalConfigCache.registration) {
|
||||
console.log('[config-cache] Returning cached registration config');
|
||||
return globalConfigCache.registration;
|
||||
}
|
||||
|
||||
@@ -244,14 +268,17 @@ export async function loadAllConfigs(): Promise<{
|
||||
*/
|
||||
export function clearConfigCache(): void {
|
||||
console.log('[config-cache] Clearing all cached configurations');
|
||||
globalConfigCache = {
|
||||
recaptcha: null,
|
||||
registration: null,
|
||||
recaptchaLoading: false,
|
||||
registrationLoading: false,
|
||||
recaptchaError: null,
|
||||
registrationError: null
|
||||
};
|
||||
|
||||
if (typeof window !== 'undefined' && (window as any).__configCache) {
|
||||
(window as any).__configCache = {
|
||||
recaptcha: null,
|
||||
registration: null,
|
||||
recaptchaLoading: false,
|
||||
registrationLoading: false,
|
||||
recaptchaError: null,
|
||||
registrationError: null
|
||||
};
|
||||
}
|
||||
|
||||
// Clear call history for circuit breaker
|
||||
Object.keys(callHistory).forEach(key => {
|
||||
@@ -263,19 +290,21 @@ export function clearConfigCache(): void {
|
||||
* Get cache status for debugging
|
||||
*/
|
||||
export function getConfigCacheStatus(): ConfigCache {
|
||||
return { ...globalConfigCache };
|
||||
return { ...getGlobalCache() };
|
||||
}
|
||||
|
||||
/**
|
||||
* Force reload specific config (bypasses cache)
|
||||
*/
|
||||
export async function reloadRecaptchaConfig(): Promise<RecaptchaConfig> {
|
||||
const globalConfigCache = getGlobalCache();
|
||||
globalConfigCache.recaptcha = null;
|
||||
globalConfigCache.recaptchaError = null;
|
||||
return getCachedRecaptchaConfig();
|
||||
}
|
||||
|
||||
export async function reloadRegistrationConfig(): Promise<RegistrationConfig> {
|
||||
const globalConfigCache = getGlobalCache();
|
||||
globalConfigCache.registration = null;
|
||||
globalConfigCache.registrationError = null;
|
||||
return getCachedRegistrationConfig();
|
||||
|
||||
Reference in New Issue
Block a user