Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions src/lib/lazyWithRetry.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { lazy, type ComponentType, createElement } from 'react';
import { logger } from "@/lib/logger";
import { attemptChunkRecovery, isChunkLoadError, extractChunkUrl } from "@/lib/chunk-recovery";
import { getFallback } from "@/components/layout/SkeletonLoaders";
import { logger } from '@/lib/logger';
import { attemptChunkRecovery, isChunkLoadError } from '@/lib/chunk-recovery';
import { getFallback } from '@/components/layout/SkeletonLoaders';

/**
* Wrapper around React.lazy that retries on chunk loading failures.
* Handles stale cache issues after deployments and Vite 502 spikes.
*/
export function lazyWithRetry<T extends ComponentType<any>>(
export function lazyWithRetry<T extends ComponentType<unknown>>(
componentImport: () => Promise<{ default: T }>,
retries = 3,
interval = 1000
interval = 1000,
): React.LazyExoticComponent<T> {
return lazy(async () => {
let lastError: Error | undefined;
Expand All @@ -23,21 +23,25 @@ export function lazyWithRetry<T extends ComponentType<any>>(

if (isChunkLoadError(error)) {
logger.warn(`Chunk load failed (attempt ${i + 1}/${retries}), retrying...`);
await new Promise(resolve => setTimeout(resolve, interval * (i + 1)));
await new Promise((resolve) => setTimeout(resolve, interval * (i + 1)));

// Última tentativa: aciona recovery agressivo (hard reload + cache bust).
if (i === retries - 1) {
const reloaded = await attemptChunkRecovery(error);
if (reloaded) {
// Retorna um componente placeholder que renderiza o esqueleto apropriado
// enquanto o hard-reload acontece no fundo.
return {
return {
default: (() => {
const url = typeof window !== 'undefined' ? window.location.pathname : '/';
return createElement('div', {
className: "animate-pulse"
}, getFallback(url));
}) as unknown as T
return createElement(
'div',
{
className: 'animate-pulse',
},
getFallback(url),
);
}) as unknown as T,
};
}
throw error;
Expand All @@ -51,4 +55,3 @@ export function lazyWithRetry<T extends ComponentType<any>>(
throw lastError;
});
}

Loading