Fix typescript compilation error on public properties
Signed-off-by: Bryan Frimin <bryan@getprobo.com> Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
committed by
Sacha Al Himdani
parent
155bbbd840
commit
fb9bce0282
@@ -1,166 +1,176 @@
|
|||||||
import {
|
import {
|
||||||
lazy as reactLazy,
|
lazy as reactLazy,
|
||||||
type LazyExoticComponent,
|
type LazyExoticComponent,
|
||||||
type ComponentType,
|
type ComponentType,
|
||||||
type FC,
|
type FC,
|
||||||
} from "react";
|
} from "react";
|
||||||
|
|
||||||
const DEFAULT_STORAGE_KEY = "reactLazyReloadedFunctions";
|
const DEFAULT_STORAGE_KEY = "reactLazyReloadedFunctions";
|
||||||
|
|
||||||
class ReloadStorage {
|
class ReloadStorage {
|
||||||
constructor(public readonly storageKey = DEFAULT_STORAGE_KEY) {}
|
public readonly storageKey: string;
|
||||||
|
|
||||||
getMap(): Map<string, number> {
|
constructor(storageKey = DEFAULT_STORAGE_KEY) {
|
||||||
const stored = sessionStorage.getItem(this.storageKey);
|
this.storageKey = storageKey;
|
||||||
|
|
||||||
try {
|
|
||||||
const parsed: unknown = stored ? JSON.parse(stored) : [];
|
|
||||||
return new Map(
|
|
||||||
Array.isArray(parsed)
|
|
||||||
? parsed.filter(
|
|
||||||
(value) =>
|
|
||||||
Array.isArray(value) &&
|
|
||||||
typeof value[0] === "string" &&
|
|
||||||
typeof value[1] === "number"
|
|
||||||
)
|
|
||||||
: []
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error parsing react-lazy storage:", error);
|
|
||||||
return new Map();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
addFunction(functionName: string): void {
|
getMap(): Map<string, number> {
|
||||||
const stored = this.getMap();
|
const stored = sessionStorage.getItem(this.storageKey);
|
||||||
stored.set(functionName, (stored.get(functionName) ?? 0) + 1);
|
|
||||||
this.save(stored);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeFunction(functionName: string): void {
|
try {
|
||||||
const stored = this.getMap();
|
const parsed: unknown = stored ? JSON.parse(stored) : [];
|
||||||
stored.delete(functionName);
|
return new Map(
|
||||||
this.save(stored);
|
Array.isArray(parsed)
|
||||||
}
|
? parsed.filter(
|
||||||
|
(value) =>
|
||||||
|
Array.isArray(value) &&
|
||||||
|
typeof value[0] === "string" &&
|
||||||
|
typeof value[1] === "number",
|
||||||
|
)
|
||||||
|
: [],
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error parsing react-lazy storage:", error);
|
||||||
|
return new Map();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected save(stored: Map<string, number>): void {
|
addFunction(functionName: string): void {
|
||||||
sessionStorage.setItem(
|
const stored = this.getMap();
|
||||||
this.storageKey,
|
stored.set(functionName, (stored.get(functionName) ?? 0) + 1);
|
||||||
JSON.stringify([...stored.entries()])
|
this.save(stored);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
removeFunction(functionName: string): void {
|
||||||
|
const stored = this.getMap();
|
||||||
|
stored.delete(functionName);
|
||||||
|
this.save(stored);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected save(stored: Map<string, number>): void {
|
||||||
|
sessionStorage.setItem(
|
||||||
|
this.storageKey,
|
||||||
|
JSON.stringify([...stored.entries()]),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ForceReloadConfig = {
|
type ForceReloadConfig = {
|
||||||
maxRetries: number;
|
maxRetries: number;
|
||||||
storageKey?: string;
|
storageKey?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type LazyConfigInit = {
|
type LazyConfigInit = {
|
||||||
forceReload?: false | Partial<ForceReloadConfig>;
|
forceReload?: false | Partial<ForceReloadConfig>;
|
||||||
importRetries?: number;
|
importRetries?: number;
|
||||||
retryDelay?: number;
|
retryDelay?: number;
|
||||||
onImportError?: (error: unknown) => void;
|
onImportError?: (error: unknown) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type LazyConfig = {
|
type LazyConfig = {
|
||||||
forceReload: ForceReloadConfig;
|
forceReload: ForceReloadConfig;
|
||||||
importRetries: number;
|
importRetries: number;
|
||||||
retryDelay: number;
|
retryDelay: number;
|
||||||
onImportError?: (error: unknown) => void;
|
onImportError?: (error: unknown) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const createConfig = (init: LazyConfigInit = {}): LazyConfig => ({
|
const createConfig = (init: LazyConfigInit = {}): LazyConfig => ({
|
||||||
forceReload: {
|
forceReload: {
|
||||||
maxRetries: 1,
|
maxRetries: 1,
|
||||||
storageKey: DEFAULT_STORAGE_KEY,
|
storageKey: DEFAULT_STORAGE_KEY,
|
||||||
...(typeof init.forceReload === "object"
|
...(typeof init.forceReload === "object"
|
||||||
? init.forceReload
|
? init.forceReload
|
||||||
: init.forceReload === false
|
: init.forceReload === false
|
||||||
? { maxRetries: 0 }
|
? { maxRetries: 0 }
|
||||||
: {}),
|
: {}),
|
||||||
},
|
},
|
||||||
importRetries:
|
importRetries:
|
||||||
typeof init.importRetries === "number"
|
typeof init.importRetries === "number"
|
||||||
? Math.max(0, init.importRetries)
|
? Math.max(0, init.importRetries)
|
||||||
: 0,
|
: 0,
|
||||||
retryDelay:
|
retryDelay:
|
||||||
typeof init.retryDelay === "number" ? Math.max(0, init.retryDelay) : 300,
|
typeof init.retryDelay === "number"
|
||||||
onImportError: init.onImportError,
|
? Math.max(0, init.retryDelay)
|
||||||
|
: 300,
|
||||||
|
onImportError: init.onImportError,
|
||||||
});
|
});
|
||||||
|
|
||||||
export function createLazy<P = {}>(config: LazyConfigInit = {}) {
|
export function createLazy<P = {}>(config: LazyConfigInit = {}) {
|
||||||
const { forceReload, importRetries, retryDelay, onImportError } =
|
const { forceReload, importRetries, retryDelay, onImportError } =
|
||||||
createConfig(config);
|
createConfig(config);
|
||||||
const reloadStorage = new ReloadStorage(forceReload.storageKey);
|
const reloadStorage = new ReloadStorage(forceReload.storageKey);
|
||||||
|
|
||||||
function enhancedLazy<T = P>(
|
function enhancedLazy<T = P>(
|
||||||
importFunction: () => Promise<{ default: ComponentType<T> }>
|
importFunction: () => Promise<{ default: ComponentType<T> }>,
|
||||||
): LazyExoticComponent<ComponentType<T>> {
|
): LazyExoticComponent<ComponentType<T>> {
|
||||||
const functionString = importFunction.toString();
|
const functionString = importFunction.toString();
|
||||||
|
|
||||||
const importWithRetry = async () => {
|
const importWithRetry = async () => {
|
||||||
let retryCount = 0;
|
let retryCount = 0;
|
||||||
|
|
||||||
const tryImport = async (): Promise<{ default: ComponentType<T> }> => {
|
const tryImport = async (): Promise<{
|
||||||
try {
|
default: ComponentType<T>;
|
||||||
return await importFunction();
|
}> => {
|
||||||
} catch (error) {
|
try {
|
||||||
if (onImportError) {
|
return await importFunction();
|
||||||
onImportError(error);
|
} catch (error) {
|
||||||
} else {
|
if (onImportError) {
|
||||||
console.error("React-lazy import error:", error);
|
onImportError(error);
|
||||||
}
|
} else {
|
||||||
|
console.error("React-lazy import error:", error);
|
||||||
|
}
|
||||||
|
|
||||||
if (retryCount < importRetries) {
|
if (retryCount < importRetries) {
|
||||||
retryCount++;
|
retryCount++;
|
||||||
|
|
||||||
if (retryDelay > 0) {
|
if (retryDelay > 0) {
|
||||||
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
await new Promise((resolve) =>
|
||||||
}
|
setTimeout(resolve, retryDelay),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tryImport();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return tryImport();
|
return tryImport();
|
||||||
}
|
};
|
||||||
|
|
||||||
throw error;
|
return reactLazy(async () => {
|
||||||
}
|
try {
|
||||||
};
|
const component = await importWithRetry();
|
||||||
|
if (forceReload.maxRetries > 0) {
|
||||||
|
reloadStorage.removeFunction(functionString);
|
||||||
|
}
|
||||||
|
return component;
|
||||||
|
} catch (error) {
|
||||||
|
if (
|
||||||
|
forceReload.maxRetries > 0 &&
|
||||||
|
(reloadStorage.getMap().get(functionString) ?? 0) <
|
||||||
|
forceReload.maxRetries
|
||||||
|
) {
|
||||||
|
reloadStorage.addFunction(functionString);
|
||||||
|
window.location.reload();
|
||||||
|
|
||||||
return tryImport();
|
const EmptyComponent: FC<T> = () => null;
|
||||||
};
|
return { default: EmptyComponent };
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return reactLazy(async () => {
|
return enhancedLazy;
|
||||||
try {
|
|
||||||
const component = await importWithRetry();
|
|
||||||
if (forceReload.maxRetries > 0) {
|
|
||||||
reloadStorage.removeFunction(functionString);
|
|
||||||
}
|
|
||||||
return component;
|
|
||||||
} catch (error) {
|
|
||||||
if (
|
|
||||||
forceReload.maxRetries > 0 &&
|
|
||||||
(reloadStorage.getMap().get(functionString) ?? 0) <
|
|
||||||
forceReload.maxRetries
|
|
||||||
) {
|
|
||||||
reloadStorage.addFunction(functionString);
|
|
||||||
window.location.reload();
|
|
||||||
|
|
||||||
const EmptyComponent: FC<T> = () => null;
|
|
||||||
return { default: EmptyComponent };
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return enhancedLazy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const lazy = createLazy({
|
export const lazy = createLazy({
|
||||||
forceReload: {
|
forceReload: {
|
||||||
maxRetries: 3,
|
maxRetries: 3,
|
||||||
storageKey: DEFAULT_STORAGE_KEY,
|
storageKey: DEFAULT_STORAGE_KEY,
|
||||||
},
|
},
|
||||||
importRetries: 3,
|
importRetries: 3,
|
||||||
retryDelay: 300,
|
retryDelay: 300,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user