mirror of
https://github.com/outline/outline.git
synced 2025-03-14 10:07:11 +00:00
42 lines
1.1 KiB
TypeScript
42 lines
1.1 KiB
TypeScript
|
import * as React from "react";
|
||
|
|
||
|
type ComponentPromise<T extends React.ComponentType<any>> = Promise<{
|
||
|
default: T;
|
||
|
}>;
|
||
|
|
||
|
/**
|
||
|
* Lazy load a component with automatic retry on failure.
|
||
|
*
|
||
|
* @param component A function that returns a promise of a component.
|
||
|
* @param retries The number of retries, defaults to 3.
|
||
|
* @param interval The interval between retries in milliseconds, defaults to 1000.
|
||
|
* @returns A lazy component.
|
||
|
*/
|
||
|
export default function lazyWithRetry<T extends React.ComponentType<any>>(
|
||
|
component: () => ComponentPromise<T>,
|
||
|
retries?: number,
|
||
|
interval?: number
|
||
|
): React.LazyExoticComponent<T> {
|
||
|
return React.lazy(() => retry(component, retries, interval));
|
||
|
}
|
||
|
|
||
|
function retry<T extends React.ComponentType<any>>(
|
||
|
fn: () => ComponentPromise<T>,
|
||
|
retriesLeft = 3,
|
||
|
interval = 1000
|
||
|
): ComponentPromise<T> {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
fn()
|
||
|
.then(resolve)
|
||
|
.catch((error) => {
|
||
|
setTimeout(() => {
|
||
|
if (retriesLeft === 1) {
|
||
|
reject(error);
|
||
|
return;
|
||
|
}
|
||
|
retry(fn, retriesLeft - 1, interval).then(resolve, reject);
|
||
|
}, interval);
|
||
|
});
|
||
|
});
|
||
|
}
|